1
2 /**
3 * Copyright (C) 2018-present MongoDB, Inc.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the Server Side Public License, version 1,
7 * as published by MongoDB, Inc.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * Server Side Public License for more details.
13 *
14 * You should have received a copy of the Server Side Public License
15 * along with this program. If not, see
16 * <http://www.mongodb.com/licensing/server-side-public-license>.
17 *
18 * As a special exception, the copyright holders give permission to link the
19 * code of portions of this program with the OpenSSL library under certain
20 * conditions as described in each individual source file and distribute
21 * linked combinations including the program with the OpenSSL library. You
22 * must comply with the Server Side Public License in all respects for
23 * all of the code used other than as permitted herein. If you modify file(s)
24 * with this exception, you may extend this exception to your version of the
25 * file(s), but you are not obligated to do so. If you do not wish to do so,
26 * delete this exception statement from your version. If you delete this
27 * exception statement from all source files in the program, then also delete
28 * it in the license file.
29 */
30
31 #pragma once
32
33 #include <map>
34 #include <vector>
35
36 #include "mongo/base/status.h"
37 #include "mongo/bson/util/builder.h"
38
39 namespace mongo {
40 namespace optionenvironment {
41
42 class Constraint;
43 class KeyConstraint;
44
45 /**
46 * Helper typedefs for the more complex C++ types supported by this Value class
47 */
48 typedef std::map<std::string, std::string> StringMap_t;
49 typedef std::vector<std::string> StringVector_t;
50
51 typedef std::string Key;
52
53 /** A simple container interface for storing various C++ values.
54 *
55 * Usage:
56 *
57 * Value intVal(2);
58 * Value stringVal("string");
59 *
60 * int intContents = 1;
61 * Status ret = stringVal.get(&intContents);
62 * // ret != Status::OK()
63 * // intContents is still 1
64 *
65 * ret = intVal.get(&intContents);
66 * // ret == Status::OK()
67 * // intContents is now 2
68 */
69 class Value {
70 public:
71 // Constructors
72
Value()73 explicit Value() : _type(None) {}
Value(StringVector_t val)74 explicit Value(StringVector_t val) : _stringVectorVal(val), _type(StringVector) {}
Value(StringMap_t val)75 explicit Value(StringMap_t val) : _stringMapVal(val), _type(StringMap) {}
Value(bool val)76 explicit Value(bool val) : _boolVal(val), _type(Bool) {}
Value(double val)77 explicit Value(double val) : _doubleVal(val), _type(Double) {}
Value(int val)78 explicit Value(int val) : _intVal(val), _type(Int) {}
Value(long val)79 explicit Value(long val) : _longVal(val), _type(Long) {}
Value(std::string val)80 explicit Value(std::string val) : _stringVal(val), _type(String) {}
Value(const char * val)81 explicit Value(const char* val) : _stringVal(val), _type(String) {}
Value(unsigned long long val)82 explicit Value(unsigned long long val) : _unsignedLongLongVal(val), _type(UnsignedLongLong) {}
Value(unsigned val)83 explicit Value(unsigned val) : _unsignedVal(val), _type(Unsigned) {}
84
85 // Access interface
86
87 Status get(StringVector_t* val) const;
88 Status get(StringMap_t* val) const;
89 Status get(bool* val) const;
90 Status get(double* val) const;
91 Status get(int* val) const;
92 Status get(long* val) const;
93 Status get(std::string* val) const;
94 Status get(unsigned long long* val) const;
95 Status get(unsigned* val) const;
96
97 // Utility functions
98
99 /**
100 * Return the value's type as a string
101 */
102 std::string typeToString() const;
103
104 /**
105 * Return true if the value was created with the no argument constructor
106 */
107 bool isEmpty() const;
108
109 /**
110 * Return true if the other Value equals this value, both in type and in contents
111 *
112 * Two empty values are equal
113 */
114 bool equal(const Value&) const;
115
116 /**
117 * Return the std::string representation of this Value. This function is used only for
118 * debugging purposes and does not output data in an easily parseable format.
119 */
120 std::string toString() const;
121
122 /**
123 * The functions below are the legacy interface to be consistent with boost::any during the
124 * transition period
125 */
126
127 /**
128 * Returns the contents of this Value as type T. Throws AssertionException if the type
129 * does not match
130 */
131 template <typename T>
132 T as() const;
133
134 /**
135 * Return the type_info for this value
136 */
137 const std::type_info& type() const;
138
139 private:
140 StringVector_t _stringVectorVal;
141 StringMap_t _stringMapVal;
142 std::string _stringVal;
143 union {
144 bool _boolVal;
145 double _doubleVal;
146 int _intVal;
147 long _longVal;
148 unsigned long long _unsignedLongLongVal;
149 unsigned _unsignedVal;
150 };
151
152 // Types currently supported by Value
153 enum Type {
154 StringVector, // std::vector<std::string>
155 StringMap, // std::map<std::string, std::string>
156 Bool, // bool
157 Double, // double
158 Int, // int
159 Long, // long
160 String, // std::string
161 UnsignedLongLong, // unsigned long long
162 Unsigned, // unsigned
163 None, // (not set)
164 };
165
166 Type _type;
167 };
168
169 template <typename T>
as()170 T Value::as() const {
171 T valueType;
172
173 Status ret = get(&valueType);
174 if (!ret.isOK()) {
175 StringBuilder message;
176 message << "failed to extract typed value from Value container: " << ret.toString();
177 uasserted(17114, message.str());
178 }
179
180 return valueType;
181 }
182
183 } // namespace optionenvironment
184 } // namespace mongo
185