generic_spec.h revision cc2ee177dbb3befca43e36cfc56778b006c3d050
1/** 2 * @file generic_spec.h 3 * Container holding an item or a special "match all" item 4 * 5 * @remark Copyright 2003 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author John Levon 9 * @author Philippe Elie 10 */ 11 12#ifndef GENERIC_SPEC_H 13#define GENERIC_SPEC_H 14 15#include <stdexcept> 16#include <string> 17#include <sstream> 18 19#include "string_manip.h" 20 21 22/** 23 * used to hold something like { int cpu_nr, bool is_all }; 24 * to store a sub part of a samples filename see PP:3.21. 25 */ 26template <class T> 27class generic_spec 28{ 29public: 30 /** 31 * build a default spec which match anything 32 */ 33 generic_spec(); 34 35 /// build a spec from a string, valid argument are "all" 36 /// or a string convertible to T through istringtream(str) >> data 37 /// conversion is strict, no space are allowed at begin or end of str 38 void set(std::string const &); 39 40 /// return true if a specific value is held by this container 41 bool is_set() const { 42 return !is_all; 43 } 44 45 /// return the specific value (only if is_set() == true) 46 T const value() const { 47 if (!is_all) 48 return data; 49 throw std::out_of_range("generic_spec holds no value"); 50 } 51 52 /// return true if rhs match this spec. Sub part of PP:3.24 53 bool match(T const & rhs) const { 54 return rhs == data; 55 } 56 57 /// return true if rhs match this spec. Sub part of PP:3.24 58 bool match(generic_spec<T> const & rhs) const { 59 return is_all || rhs.is_all || rhs.data == data; 60 } 61 62private: 63 T data; 64 bool is_all; 65}; 66 67 68template <class T> 69generic_spec<T>::generic_spec() 70 : 71 data(T()), 72 is_all(true) 73{ 74} 75 76 77template <class T> 78void generic_spec<T>::set(std::string const & str) 79{ 80 if (str == "all") { 81 is_all = true; 82 return; 83 } 84 85 is_all = false; 86 data = op_lexical_cast<T>(str); 87} 88 89 90/// We don't use generic_spec<string>, since it's probably an error to try 91/// to use generic_spec<string> we specialize but don't define it to get a 92/// link error (using generic_spec<string> is problematic because g.set("all") 93/// is ambiguous) 94template <> 95void generic_spec<std::string>::set(std::string const & str); 96 97#endif /* !GENERIC_SPEC_H */ 98