C Client-Side SDK
LaunchDarkly SDK
value.hpp
1 #pragma once
2 
3 #include <unordered_map>
4 #include <vector>
5 #include <string>
6 #include <utility> // initializer_list, pair, swap
7 #include <cstddef> // size_t
8 
9 extern "C" {
10 #include <launchdarkly/memory.h>
12 }
13 
14 namespace launchdarkly {
15 
16 class Value;
17 class Array {
18  public:
19  ~Array();
20  explicit Array();
21  Array(std::initializer_list<Value>);
22  Array(const Array&) = delete;
23  Array(Array&&) = delete;
24  Array& operator=(const Array&) = delete;
25  Array& operator=(Array&&) noexcept = delete;
26  friend bool operator== (const Array&, const Array&) = delete;
27 
28  Array& add(const Value&);
29  Array& add(Value&&);
30  Array& add(bool);
31  Array& add(double);
32  Array& add(const char *);
33  Array& add(const std::string&);
34 
35  Value build() const;
36  private:
37  struct LDArray *ptr;
38 }; // class Array
39 
40 
41 
42 class Object {
43  public:
44  ~Object();
45  explicit Object();
46  Object(std::initializer_list<std::pair<const char*, Value>>);
47  Object(const Object&) = delete;
48  Object(Object&&) = delete;
49  Object& operator=(const Object&) = delete;
50  Object& operator=(Object&&) noexcept = delete;
51  friend bool operator== (const Object&, const Object&) = delete;
52 
53  void set(const char* key, const Value& value);
54  void set(const char *key, Value&& value);
55 
56  void set(const char *key, bool value);
57  void set(const char *key, double value);
58  void set(const char *key, const char *value);
59  void set(const char *key, const std::string& value);
60 
61  Value build() const;
62  private:
63  struct LDObject *ptr;
64 }; // class Object
65 
66 class Value {
67  public:
68  enum class Type {
76  Null,
80  Bool,
84  Number,
88  String,
92  Array,
96  Object
97  };
98 
104  explicit Value(struct LDValue *ptr)
105  :ptr{ptr} {}
106 
111  explicit Value()
112  :ptr {LDValue_Null()} {}
113 
118  explicit Value(bool b)
119  :ptr{LDValue_Bool(b ? LDBooleanTrue : LDBooleanFalse)} {}
120 
125  explicit Value(double b)
126  :ptr { LDValue_Number(b) } {}
127 
133  explicit Value(const char *b)
134  :ptr { LDValue_ConstantString(b)} {}
135 
140  explicit Value(const std::string& b)
141  :ptr { LDValue_OwnedString(b.c_str())} {}
142 
147  Value(const Array& array)
148  :ptr{ array.build().release() } {}
149 
154  Value(const Object& obj)
155  :ptr{ obj.build().release() } {}
156 
161  Value(const Value& other)
162  :ptr { LDValue_Clone(other.ptr) } {}
163 
168  Value(Value&& other) noexcept
169  :ptr {other.release()} {}
170 
175  Value& operator=(const Value& other) {
176  return *this = Value(other);
177  }
178 
183  Value& operator=(Value&& other) noexcept
184  {
185  // destructor of other will free this object's previous ptr.
186  std::swap(ptr, other.ptr);
187  return *this;
188  }
189 
193  ~Value() {
194  LDValue_Free(ptr);
195  }
196 
197 
198  friend bool operator== (const Value& c1, const Value& c2) {
199  return LDValue_Equal(c1.ptr, c2.ptr);
200  }
201 
202  friend bool operator!= (const Value& c1, const Value& c2) {
203  return !(c1 == c2);
204  }
205 
206 
211  Type type() const {
212  switch (LDValue_Type(ptr)) {
214  return Type::Unrecognized;
215  case LDValueType_Null:
216  return Type::Null;
217  case LDValueType_Bool:
218  return Type::Bool;
219  case LDValueType_Number:
220  return Type::Number;
221  case LDValueType_String:
222  return Type::String;
223  case LDValueType_Array:
224  return Type::Array;
225  case LDValueType_Object:
226  return Type::Object;
227  }
228  }
229 
234  std::string serialize_json() {
235  char *serialized = LDValue_SerializeJSON(ptr);
236  std::string r = serialized;
237  LDFree(serialized);
238  return r;
239  }
240 
245  std::string serialize_formatted_json() {
246  char *serialized = LDValue_SerializeFormattedJSON(ptr);
247  std::string r = serialized;
248  LDFree(serialized);
249  return r;
250  }
251 
258  static Value parse_json(const char *json) {
259  struct LDValue* parsed = LDValue_ParseJSON(json);
260  if (!parsed) {
261  return Value();
262  }
263  return Value(parsed);
264  }
265 
270  bool get_bool() const {
271  return LDValue_GetBool(ptr);
272  }
273 
278  std::string get_string() const {
279  return LDValue_GetString(ptr);
280  }
281 
286  double get_number() const {
287  return LDValue_GetNumber(ptr);
288  }
289 
296  std::vector<Value>
297  into_vector() const {
298  std::vector<Value> values;
299  for (struct LDIter *it = LDValue_GetIter(ptr); it; it = LDIter_Next(it)) {
300  values.emplace_back(LDValue_Clone(LDIter_Val(it)));
301  }
302  return values;
303  }
304 
311  std::unordered_map<std::string, Value>
313  std::unordered_map<std::string, Value> map;
314  if (this->type() != Type::Object) {
315  return map;
316  }
317  for (struct LDIter *it = LDValue_GetIter(ptr); it; it = LDIter_Next(it)) {
318  map.emplace(LDIter_Key(it), LDValue_Clone(LDIter_Val(it)));
319  }
320  return map;
321  }
322 
327  size_t count() const {
328  return LDValue_Count(ptr);
329  }
330 
335  bool is_null() const {
336  return type() == Type::Null;
337  }
338 
346  struct LDValue* release() {
347  struct LDValue* raw = ptr;
348  ptr = nullptr;
349  return raw;
350  }
351 
352 
353  private:
354  struct LDValue *ptr;
355 }; // class Value
356 
357 
358 Array::~Array() {
359  LDArray_Free(ptr);
360 }
361 
362 Array::Array() :ptr{LDArray_New()} {}
363 
364 Array::Array(std::initializer_list<Value> init) :ptr{LDArray_New()} {
365  for (auto copy : init) {
366  LDArray_Add(ptr, copy.release());
367  }
368 }
369 
370 Array& Array::add(const Value& v) {
371  Value clone {v};
372  LDArray_Add(ptr, clone.release());
373  return *this;
374 }
375 
376 Array& Array::add(Value&& v) {
377  LDArray_Add(ptr, v.release());
378  return *this;
379 }
380 
381 Array& Array::add(bool b) { add(Value(b)); return *this;}
382 Array& Array::add(double b) { add(Value(b)); return *this; }
383 Array& Array::add(const char *b) { add(Value(b)); return *this; }
384 Array& Array::add(const std::string& b) { add(Value(b)); return *this; }
385 
386 Value Array::build() const {
387  return Value(LDArray_Build(ptr));
388 }
389 
390 
391 Object::Object()
392 :ptr{LDObject_New()} {}
393 
394 Object::Object(std::initializer_list<std::pair<const char*, Value>> init)
395 :ptr{LDObject_New()} {
396  for (auto kv : init) {
397  LDObject_AddConstantKey(ptr, kv.first, kv.second.release());
398  }
399 }
400 
401 Object::~Object() {
402  LDObject_Free(ptr);
403 }
404 
405 
406 void Object::set(const char* key, const Value& value) {
407  Value clone {value};
408  LDObject_AddConstantKey(ptr, key, clone.release());
409 }
410 
411 void Object::set(const char *key, Value&& value) {
412  LDObject_AddConstantKey(ptr, key, value.release());
413 }
414 
415 void Object::set(const char *key, bool value) { set(key, Value(value)); }
416 void Object::set(const char *key, double value) { set(key, Value(value)); }
417 void Object::set(const char *key, const char *val) { set(key, Value(val)); }
418 void Object::set(const char *key, const std::string& val) { set(key, Value(val)); }
419 
420 Value Object::build() const {
421  return Value(LDObject_Build(ptr));
422 }
423 
424 } // namespace launchdarkly
LDValueType_Object
@ LDValueType_Object
Definition: ldvalue.h:42
LDObject_New
struct LDObject * LDObject_New(void)
launchdarkly::Value
Definition: value.hpp:66
LDValueType_Number
@ LDValueType_Number
Definition: ldvalue.h:30
LDObject_Free
void LDObject_Free(struct LDObject *obj)
LDArray_New
struct LDArray * LDArray_New(void)
LDValueType_Unrecognized
@ LDValueType_Unrecognized
Definition: ldvalue.h:18
LDValue_GetString
const char * LDValue_GetString(struct LDValue *value)
launchdarkly::Value::Type::Object
@ Object
launchdarkly::Value::operator=
Value & operator=(Value &&other) noexcept
Definition: value.hpp:183
launchdarkly::Value::is_null
bool is_null() const
Definition: value.hpp:335
launchdarkly::Value::~Value
~Value()
Definition: value.hpp:193
LDArray_Free
void LDArray_Free(struct LDArray *array)
launchdarkly::Value::Type
Type
Definition: value.hpp:68
launchdarkly::Value::get_bool
bool get_bool() const
Definition: value.hpp:270
LDValue_Number
struct LDValue * LDValue_Number(double number)
launchdarkly::Value::Type::Number
@ Number
LDValue_OwnedString
struct LDValue * LDValue_OwnedString(const char *string)
launchdarkly::Value::parse_json
static Value parse_json(const char *json)
Definition: value.hpp:258
LDValue_Count
unsigned int LDValue_Count(struct LDValue *value)
LDValueType_Null
@ LDValueType_Null
Definition: ldvalue.h:22
launchdarkly::Value::Type::Null
@ Null
launchdarkly::Value::Value
Value(Value &&other) noexcept
Definition: value.hpp:168
launchdarkly::Value::get_string
std::string get_string() const
Definition: value.hpp:278
LDObject_AddConstantKey
void LDObject_AddConstantKey(struct LDObject *obj, const char *key, struct LDValue *value)
launchdarkly::Value::Value
Value(const Object &obj)
Definition: value.hpp:154
LDValue_ParseJSON
struct LDValue * LDValue_ParseJSON(const char *json)
LDValue_GetIter
struct LDIter * LDValue_GetIter(struct LDValue *value)
LDValue_Clone
struct LDValue * LDValue_Clone(struct LDValue *source)
LDObject_Build
struct LDValue * LDObject_Build(struct LDObject *obj)
launchdarkly::Value::release
struct LDValue * release()
Definition: value.hpp:346
launchdarkly::Value::operator=
Value & operator=(const Value &other)
Definition: value.hpp:175
launchdarkly::Value::Value
Value(bool b)
Definition: value.hpp:118
LDValue_Bool
struct LDValue * LDValue_Bool(LDBoolean boolean)
launchdarkly::Value::Value
Value(const Array &array)
Definition: value.hpp:147
launchdarkly::Value::Type::Bool
@ Bool
launchdarkly::Array
Definition: value.hpp:17
LDArray
@ LDArray
JSON integer indexed array.
Definition: json.h:29
LDValue_SerializeJSON
char * LDValue_SerializeJSON(struct LDValue *value)
LDFree
void LDFree(void *const buffer)
Equivalent to free
LDValue_Equal
LDBoolean LDValue_Equal(struct LDValue *a, struct LDValue *b)
launchdarkly::Object
Definition: value.hpp:42
launchdarkly::Value::serialize_json
std::string serialize_json()
Definition: value.hpp:234
launchdarkly::Value::Type::Unrecognized
@ Unrecognized
launchdarkly::Value::Value
Value(const std::string &b)
Definition: value.hpp:140
LDIter_Key
const char * LDIter_Key(struct LDIter *iterator)
LDIter_Next
struct LDIter * LDIter_Next(struct LDIter *iterator)
launchdarkly::Value::get_number
double get_number() const
Definition: value.hpp:286
launchdarkly::Value::Value
Value()
Definition: value.hpp:111
launchdarkly::Value::Type::String
@ String
launchdarkly::Value::count
size_t count() const
Definition: value.hpp:327
launchdarkly::Value::into_vector
std::vector< Value > into_vector() const
Definition: value.hpp:297
launchdarkly::Value::Type::Array
@ Array
LDValue_Null
struct LDValue * LDValue_Null(void)
LDValue_ConstantString
struct LDValue * LDValue_ConstantString(const char *string)
LDArray_Add
void LDArray_Add(struct LDArray *array, struct LDValue *value)
LDValueType_String
@ LDValueType_String
Definition: ldvalue.h:34
launchdarkly::Value::Value
Value(const Value &other)
Definition: value.hpp:161
LDValue_GetBool
LDBoolean LDValue_GetBool(struct LDValue *value)
LDValue_SerializeFormattedJSON
char * LDValue_SerializeFormattedJSON(struct LDValue *value)
LDValueType_Bool
@ LDValueType_Bool
Definition: ldvalue.h:26
LDArray_Build
struct LDValue * LDArray_Build(struct LDArray *array)
ldvalue.h
LDValues represent immutable JSON values.
launchdarkly::Value::Value
Value(double b)
Definition: value.hpp:125
LDIter_Val
struct LDValue * LDIter_Val(struct LDIter *iterator)
launchdarkly::Value::Value
Value(struct LDValue *ptr)
Definition: value.hpp:104
LDValue_Free
void LDValue_Free(struct LDValue *value)
LDObject
@ LDObject
JSON string indexed map.
Definition: json.h:27
LDValueType_Array
@ LDValueType_Array
Definition: ldvalue.h:38
launchdarkly::Value::serialize_formatted_json
std::string serialize_formatted_json()
Definition: value.hpp:245
launchdarkly::Value::into_unordered_map
std::unordered_map< std::string, Value > into_unordered_map() const
Definition: value.hpp:312
LDValue_Type
enum LDValueType LDValue_Type(struct LDValue *value)
LDValue_GetNumber
double LDValue_GetNumber(struct LDValue *value)
memory.h
Public API. Operations for managing memory.
launchdarkly::Value::Value
Value(const char *b)
Definition: value.hpp:133
launchdarkly::Value::type
Type type() const
Definition: value.hpp:211