• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017-2018 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef ARM_COMPUTE_UTILS_ENUMLISTOPTION
25 #define ARM_COMPUTE_UTILS_ENUMLISTOPTION
26 
27 #include "Option.h"
28 
29 #include <initializer_list>
30 #include <set>
31 #include <sstream>
32 #include <stdexcept>
33 #include <string>
34 #include <vector>
35 
36 namespace arm_compute
37 {
38 namespace utils
39 {
40 /** Implementation of an option that accepts any number of values from a fixed set. */
41 template <typename T>
42 class EnumListOption : public Option
43 {
44 public:
45     /** Construct option with allowed values.
46      *
47      * @param[in] name           Name of the option.
48      * @param[in] allowed_values Set of allowed values for the option.
49      */
50     EnumListOption(std::string name, std::set<T> allowed_values);
51 
52     /** Construct option with allowed values, a fixed number of accepted values and default values for the option.
53      *
54      * @param[in] name           Name of the option.
55      * @param[in] allowed_values Set of allowed values for the option.
56      * @param[in] default_values Default values.
57      */
58     EnumListOption(std::string name, std::set<T> allowed_values, std::initializer_list<T> &&default_values);
59 
60     bool parse(std::string value) override;
61     std::string help() const override;
62 
63     /** Get the values of the option.
64      *
65      * @return a list of the selected option values.
66      */
67     const std::vector<T> &value() const;
68 
69 private:
70     std::vector<T> _values{};
71     std::set<T>    _allowed_values{};
72 };
73 
74 template <typename T>
EnumListOption(std::string name,std::set<T> allowed_values)75 inline EnumListOption<T>::EnumListOption(std::string name, std::set<T> allowed_values)
76     : Option{ std::move(name) }, _allowed_values{ std::move(allowed_values) }
77 {
78 }
79 
80 template <typename T>
EnumListOption(std::string name,std::set<T> allowed_values,std::initializer_list<T> && default_values)81 inline EnumListOption<T>::EnumListOption(std::string name, std::set<T> allowed_values, std::initializer_list<T> &&default_values)
82     : Option{ std::move(name), false, true }, _values{ std::forward<std::initializer_list<T>>(default_values) }, _allowed_values{ std::move(allowed_values) }
83 {
84 }
85 
86 template <typename T>
parse(std::string value)87 bool EnumListOption<T>::parse(std::string value)
88 {
89     // Remove default values
90     _values.clear();
91     _is_set = true;
92 
93     std::stringstream stream{ value };
94     std::string       item;
95 
96     while(!std::getline(stream, item, ',').fail())
97     {
98         try
99         {
100             std::stringstream item_stream(item);
101             T                 typed_value{};
102 
103             item_stream >> typed_value;
104 
105             if(!item_stream.fail())
106             {
107                 if(_allowed_values.count(typed_value) == 0)
108                 {
109                     _is_set = false;
110                     continue;
111                 }
112 
113                 _values.emplace_back(typed_value);
114             }
115 
116             _is_set = _is_set && !item_stream.fail();
117         }
118         catch(const std::invalid_argument &)
119         {
120             _is_set = false;
121         }
122     }
123 
124     return _is_set;
125 }
126 
127 template <typename T>
help()128 std::string EnumListOption<T>::help() const
129 {
130     std::stringstream msg;
131     msg << "--" + name() + "={";
132 
133     for(const auto &value : _allowed_values)
134     {
135         msg << value << ",";
136     }
137 
138     msg << "}[,{...}[,...]] - " << _help;
139 
140     return msg.str();
141 }
142 
143 template <typename T>
value()144 inline const std::vector<T> &EnumListOption<T>::value() const
145 {
146     return _values;
147 }
148 } // namespace utils
149 } // namespace arm_compute
150 #endif /* ARM_COMPUTE_UTILS_ENUMLISTOPTION */
151