blob: 18bff513bcbc0616239c68bca316b9aa5fc73358 [file] [log] [blame]
Mike Dodd8cfa7022010-11-17 11:12:26 -08001/**
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 */