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 */ 26 template <class T> 27 class generic_spec 28 { 29 public: 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 is_set()41 bool is_set() const { 42 return !is_all; 43 } 44 45 /// return the specific value (only if is_set() == true) value()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 match(T const & rhs)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 match(generic_spec<T> const & rhs)58 bool match(generic_spec<T> const & rhs) const { 59 return is_all || rhs.is_all || rhs.data == data; 60 } 61 62 private: 63 T data; 64 bool is_all; 65 }; 66 67 68 template <class T> generic_spec()69generic_spec<T>::generic_spec() 70 : 71 data(T()), 72 is_all(true) 73 { 74 } 75 76 77 template <class T> set(std::string const & str)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) 94 template <> 95 void generic_spec<std::string>::set(std::string const & str); 96 97 #endif /* !GENERIC_SPEC_H */ 98