summaryrefslogtreecommitdiff
path: root/ext/librethinkdbxx/src/datum.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/librethinkdbxx/src/datum.h')
-rw-r--r--ext/librethinkdbxx/src/datum.h287
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;
-};
-
-}