| /** |
| * @file generic_spec.h |
| * Container holding an item or a special "match all" item |
| * |
| * @remark Copyright 2003 OProfile authors |
| * @remark Read the file COPYING |
| * |
| * @author John Levon |
| * @author Philippe Elie |
| */ |
| |
| #ifndef GENERIC_SPEC_H |
| #define GENERIC_SPEC_H |
| |
| #include <stdexcept> |
| #include <string> |
| #include <sstream> |
| |
| #include "string_manip.h" |
| |
| |
| /** |
| * used to hold something like { int cpu_nr, bool is_all }; |
| * to store a sub part of a samples filename see PP:3.21. |
| */ |
| template <class T> |
| class generic_spec |
| { |
| public: |
| /** |
| * build a default spec which match anything |
| */ |
| generic_spec(); |
| |
| /// build a spec from a string, valid argument are "all" |
| /// or a string convertible to T through istringtream(str) >> data |
| /// conversion is strict, no space are allowed at begin or end of str |
| void set(std::string const &); |
| |
| /// return true if a specific value is held by this container |
| bool is_set() const { |
| return !is_all; |
| } |
| |
| /// return the specific value (only if is_set() == true) |
| T const value() const { |
| if (!is_all) |
| return data; |
| throw std::out_of_range("generic_spec holds no value"); |
| } |
| |
| /// return true if rhs match this spec. Sub part of PP:3.24 |
| bool match(T const & rhs) const { |
| return rhs == data; |
| } |
| |
| /// return true if rhs match this spec. Sub part of PP:3.24 |
| bool match(generic_spec<T> const & rhs) const { |
| return is_all || rhs.is_all || rhs.data == data; |
| } |
| |
| private: |
| T data; |
| bool is_all; |
| }; |
| |
| |
| template <class T> |
| generic_spec<T>::generic_spec() |
| : |
| data(T()), |
| is_all(true) |
| { |
| } |
| |
| |
| template <class T> |
| void generic_spec<T>::set(std::string const & str) |
| { |
| if (str == "all") { |
| is_all = true; |
| return; |
| } |
| |
| is_all = false; |
| data = op_lexical_cast<T>(str); |
| } |
| |
| |
| /// We don't use generic_spec<string>, since it's probably an error to try |
| /// to use generic_spec<string> we specialize but don't define it to get a |
| /// link error (using generic_spec<string> is problematic because g.set("all") |
| /// is ambiguous) |
| template <> |
| void generic_spec<std::string>::set(std::string const & str); |
| |
| #endif /* !GENERIC_SPEC_H */ |