Add Possibility to set MultiValue Parameters.
[command.git] / include / multiValue.h
1 #ifndef __COMMAND_MULTIVALUE_H
2 #define __COMMAND_MULTIVALUE_H
3
4 #include <iostream>
5
6 #include "parameter.h"
7
8 namespace command {
9     /**
10      * Multiple Value Parameter decorator. Allows Parameters to understand
11      * many values.
12      *
13      * Example:
14      *  - separator: ","
15      *  - multiValue: "0,1,2,3,4,5,6,7,8,9"
16      *
17      * Example usage:
18      *  - ./myprog ARGUMENT,ARGUMENT,ARGUMENT,ARGUMENT
19      *  - ./myprog OPTION_NAME=VALUE,VALUE,VALUE,VALUE
20      */
21     class MultiValue : public Parameter {
22     protected:
23         /**
24          * Parameter which will be treated as containing multiple values
25          */
26         Parameter * parameter;
27
28         std::vector<std::string> values;
29
30         std::string separator;
31
32     public:
33         /**
34          * Default constructor.
35          *
36          * @param parameter Parameter which will be treated as containing multiple values
37          */
38         MultiValue(std::string separator, Parameter * parameter)
39             : Parameter(parameter->describe()), parameter(parameter),
40                 separator(separator) {
41         }
42
43         /**
44          * Default destructor. Releases allocated memory
45          */
46         virtual ~MultiValue() {
47             delete parameter;
48         }
49
50         /**
51          * Wrapper method around passed Parameter::handle().
52          *
53          * \inheritdoc
54          */
55         virtual void handle() {
56             for (std::string value : values) {
57                 parameter->understand(value);
58                 parameter->handle();
59             }
60         }
61
62         /**
63          * Wrapper method around passed Parameter::understand()
64          *
65          * @param argv command line value against which test will be made
66          *
67          * \inheritdoc
68          */
69         virtual bool understand(const std::string & value) {
70             size_t start = 0;
71             size_t pos = 0;
72             bool _understand = true;
73
74             do {
75                 pos = value.find(separator, start);
76                 values.push_back(value.substr(start, pos-start));
77                 _understand &= parameter->understand(values.back());
78                 start = pos + 1;
79             } while ((pos != std::string::npos) && (start < value.size()));
80
81             return _understand;
82         }
83
84         /**
85          * Wrapper method around passed Parameter::isRequired().
86          * Indicates if current Parameter is required.
87          *
88          * @return true if Parameter is required, false otherwise
89          */
90         virtual bool isRequired() {
91             return parameter->isRequired();
92         };
93
94         /**
95          * Wrapper method around passed Parameter::isUsed().
96          *
97          * \inheritdoc
98          */
99         virtual bool isUsed() {
100             return parameter->isUsed();
101         };
102     };
103 }
104
105 #endif /* __COMMAND_PARAMETER_H */