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