diff options
Diffstat (limited to 'ext/librethinkdbxx/src/datum.h')
-rw-r--r-- | ext/librethinkdbxx/src/datum.h | 287 |
1 files changed, 0 insertions, 287 deletions
diff --git a/ext/librethinkdbxx/src/datum.h b/ext/librethinkdbxx/src/datum.h deleted file mode 100644 index 051e2ca2..00000000 --- a/ext/librethinkdbxx/src/datum.h +++ /dev/null @@ -1,287 +0,0 @@ -#pragma once - -#include <string> -#include <vector> -#include <map> -#include <functional> - -#include "protocol_defs.h" -#include "error.h" -#include "types.h" - -namespace RethinkDB { - -class Cursor; - -// The type of data stored in a RethinkDB database. -// The following JSON types are represented in a Datum as -// * null -> Nil -// * boolean -> bool -// * number -> double -// * unicode strings -> std::string -// * array -> Array (aka std::vector<Datum> -// * object -> Object (aka std::map<std::string, Datum>> -// Datums can also contain one of the following extra types -// * binary strings -> Binary -// * timestamps -> Time -// * points. lines and polygons -> not implemented -class Datum { -public: - Datum() : type(Type::INVALID), value() {} - Datum(Nil) : type(Type::NIL), value() { } - Datum(bool boolean_) : type(Type::BOOLEAN), value(boolean_) { } - Datum(double number_) : type(Type::NUMBER), value(number_) { } - Datum(const std::string& string_) : type(Type::STRING), value(string_) { } - Datum(std::string&& string_) : type(Type::STRING), value(std::move(string_)) { } - Datum(const Array& array_) : type(Type::ARRAY), value(array_) { } - Datum(Array&& array_) : type(Type::ARRAY), value(std::move(array_)) { } - Datum(const Binary& binary) : type(Type::BINARY), value(binary) { } - Datum(Binary&& binary) : type(Type::BINARY), value(std::move(binary)) { } - Datum(const Time time) : type(Type::TIME), value(time) { } - Datum(const Object& object_) : type(Type::OBJECT), value(object_) { } - Datum(Object&& object_) : type(Type::OBJECT), value(std::move(object_)) { } - Datum(const Datum& other) : type(other.type), value(other.type, other.value) { } - Datum(Datum&& other) : type(other.type), value(other.type, std::move(other.value)) { } - - Datum& operator=(const Datum& other) { - value.destroy(type); - type = other.type; - value.set(type, other.value); - return *this; - } - - Datum& operator=(Datum&& other) { - value.destroy(type); - type = other.type; - value.set(type, std::move(other.value)); - return *this; - } - - Datum(unsigned short number_) : Datum(static_cast<double>(number_)) { } - Datum(signed short number_) : Datum(static_cast<double>(number_)) { } - Datum(unsigned int number_) : Datum(static_cast<double>(number_)) { } - Datum(signed int number_) : Datum(static_cast<double>(number_)) { } - Datum(unsigned long number_) : Datum(static_cast<double>(number_)) { } - Datum(signed long number_) : Datum(static_cast<double>(number_)) { } - Datum(unsigned long long number_) : Datum(static_cast<double>(number_)) { } - Datum(signed long long number_) : Datum(static_cast<double>(number_)) { } - - Datum(Protocol::Term::TermType type) : Datum(static_cast<double>(type)) { } - Datum(const char* string) : Datum(static_cast<std::string>(string)) { } - - // Cursors are implicitly converted into datums - Datum(Cursor&&); - Datum(const Cursor&); - - template <class T> - Datum(const std::map<std::string, T>& map) : type(Type::OBJECT), value(Object()) { - for (const auto& it : map) { - value.object.emplace(it.left, Datum(it.right)); - } - } - - template <class T> - Datum(std::map<std::string, T>&& map) : type(Type::OBJECT), value(Object()) { - for (auto& it : map) { - value.object.emplace(it.first, Datum(std::move(it.second))); - } - } - - template <class T> - Datum(const std::vector<T>& vec) : type(Type::ARRAY), value(Array()) { - for (const auto& it : vec) { - value.array.emplace_back(it); - } - } - - template <class T> - Datum(std::vector<T>&& vec) : type(Type::ARRAY), value(Array()) { - for (auto& it : vec) { - value.array.emplace_back(std::move(it)); - } - } - - ~Datum() { - value.destroy(type); - } - - // Apply a visitor - template <class R, class F, class ...A> - R apply(F f, A&& ...args) const & { - switch (type) { - case Type::NIL: return f(Nil(), std::forward<A>(args)...); break; - case Type::BOOLEAN: return f(value.boolean, std::forward<A>(args)...); break; - case Type::NUMBER: return f(value.number, std::forward<A>(args)...); break; - case Type::STRING: return f(value.string, std::forward<A>(args)...); break; - case Type::OBJECT: return f(value.object, std::forward<A>(args)...); break; - case Type::ARRAY: return f(value.array, std::forward<A>(args)...); break; - case Type::BINARY: return f(value.binary, std::forward<A>(args)...); break; - case Type::TIME: return f(value.time, std::forward<A>(args)...); break; - default: - throw Error("internal error: no such datum type %d", static_cast<int>(type)); - } - } - - template <class R, class F, class ...A> - R apply(F f, A&& ...args) && { - switch (type) { - case Type::NIL: return f(Nil(), std::forward<A>(args)...); break; - case Type::BOOLEAN: return f(std::move(value.boolean), std::forward<A>(args)...); break; - case Type::NUMBER: return f(std::move(value.number), std::forward<A>(args)...); break; - case Type::STRING: return f(std::move(value.string), std::forward<A>(args)...); break; - case Type::OBJECT: return f(std::move(value.object), std::forward<A>(args)...); break; - case Type::ARRAY: return f(std::move(value.array), std::forward<A>(args)...); break; - case Type::BINARY: return f(std::move(value.binary), std::forward<A>(args)...); break; - case Type::TIME: return f(std::move(value.time), std::forward<A>(args)...); break; - default: - throw Error("internal error: no such datum type %d", static_cast<int>(type)); - } - } - - bool is_nil() const; - bool is_boolean() const; - bool is_number() const; - bool is_string() const; - bool is_object() const; - bool is_array() const; - bool is_binary() const; - bool is_time() const; - - // get_* returns nullptr if the datum has a different type - - bool* get_boolean(); - const bool* get_boolean() const; - double* get_number(); - const double* get_number() const; - std::string* get_string(); - const std::string* get_string() const; - Object* get_object(); - const Object* get_object() const; - Datum* get_field(std::string); - const Datum* get_field(std::string) const; - Array* get_array(); - const Array* get_array() const; - Datum* get_nth(size_t); - const Datum* get_nth(size_t) const; - Binary* get_binary(); - const Binary* get_binary() const; - Time* get_time(); - const Time* get_time() const; - - // extract_* throws an exception if the types don't match - - bool& extract_boolean(); - double& extract_number(); - std::string& extract_string(); - Object& extract_object(); - Datum& extract_field(std::string); - Array& extract_array(); - Datum& extract_nth(size_t); - Binary& extract_binary(); - Time& extract_time(); - - // negative, zero or positive if this datum is smaller, identical or larger than the other one, respectively - // This is meant to match the results of RethinkDB's comparison operators - int compare(const Datum&) const; - - // Deep equality - bool operator== (const Datum&) const; - - // Recusively replace non-JSON types into objects that represent them - Datum to_raw() const; - - // Recursively replace objects with a $reql_type$ field into the datum they represent - Datum from_raw() const; - - template <class json_writer_t> void write_json(json_writer_t *writer) const; - - std::string as_json() const; - static Datum from_json(const std::string&); - - bool is_valid() const { return type != Type::INVALID; } - -private: - enum class Type { - INVALID, // default constructed - ARRAY, BOOLEAN, NIL, NUMBER, OBJECT, BINARY, STRING, TIME - // POINT, LINE, POLYGON - }; - Type type; - - union datum_value { - bool boolean; - double number; - std::string string; - Object object; - Array array; - Binary binary; - Time time; - - datum_value() { } - datum_value(bool boolean_) : boolean(boolean_) { } - datum_value(double number_) : number(number_) { } - datum_value(const std::string& string_) : string(string_) { } - datum_value(std::string&& string_) : string(std::move(string_)) { } - datum_value(const Object& object_) : object(object_) { } - datum_value(Object&& object_) : object(std::move(object_)) { } - datum_value(const Array& array_) : array(array_) { } - datum_value(Array&& array_) : array(std::move(array_)) { } - datum_value(const Binary& binary_) : binary(binary_) { } - datum_value(Binary&& binary_) : binary(std::move(binary_)) { } - datum_value(Time time) : time(std::move(time)) { } - - datum_value(Type type, const datum_value& other){ - set(type, other); - } - - datum_value(Type type, datum_value&& other){ - set(type, std::move(other)); - } - - void set(Type type, datum_value&& other) { - switch(type){ - case Type::NIL: case Type::INVALID: break; - case Type::BOOLEAN: new (this) bool(other.boolean); break; - case Type::NUMBER: new (this) double(other.number); break; - case Type::STRING: new (this) std::string(std::move(other.string)); break; - case Type::OBJECT: new (this) Object(std::move(other.object)); break; - case Type::ARRAY: new (this) Array(std::move(other.array)); break; - case Type::BINARY: new (this) Binary(std::move(other.binary)); break; - case Type::TIME: new (this) Time(std::move(other.time)); break; - } - } - - void set(Type type, const datum_value& other) { - switch(type){ - case Type::NIL: case Type::INVALID: break; - case Type::BOOLEAN: new (this) bool(other.boolean); break; - case Type::NUMBER: new (this) double(other.number); break; - case Type::STRING: new (this) std::string(other.string); break; - case Type::OBJECT: new (this) Object(other.object); break; - case Type::ARRAY: new (this) Array(other.array); break; - case Type::BINARY: new (this) Binary(other.binary); break; - case Type::TIME: new (this) Time(other.time); break; - } - } - - void destroy(Type type) { - switch(type){ - case Type::INVALID: break; - case Type::NIL: break; - case Type::BOOLEAN: break; - case Type::NUMBER: break; - case Type::STRING: { typedef std::string str; string.~str(); } break; - case Type::OBJECT: object.~Object(); break; - case Type::ARRAY: array.~Array(); break; - case Type::BINARY: binary.~Binary(); break; - case Type::TIME: time.~Time(); break; - } - } - - ~datum_value() { } - }; - - datum_value value; -}; - -} |