90de29a9787d5f229de0935674dc0f9fb4a2e528
[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 = parameter->valuePosition(value);
71             size_t pos = 0;
72             bool _understand = true;
73             std::string prefix = "";
74
75             if (start > 0) {
76                 prefix = value.substr(0, ++start);// always count: "="
77             }
78
79             do {
80                 pos = value.find(separator, start);
81                 values.push_back(prefix + value.substr(start, pos-start));
82                 _understand &= parameter->understand(values.back());
83                 start = pos + 1;
84             } while ((pos != std::string::npos) && (start < value.size()));
85
86             return _understand;
87         }
88
89         /**
90          * Wrapper method around passed Parameter::isRequired().
91          * Indicates if current Parameter is required.
92          *
93          * @return true if Parameter is required, false otherwise
94          */
95         virtual bool isRequired() {
96             return parameter->isRequired();
97         };
98
99         /**
100          * Wrapper method around passed Parameter::isUsed().
101          *
102          * \inheritdoc
103          */
104         virtual bool isUsed() {
105             return parameter->isUsed();
106         };
107
108         /**
109          * Wrapper method around passed Parameter::valuePosition().
110          *
111          * \inheritdoc
112          */
113         virtual unsigned int valuePosition(const std::string & value) {
114             return parameter->valuePosition(value);
115         }
116     };
117 }
118
119 #endif /* __COMMAND_PARAMETER_H */