Program Listing for File Variant.hpp¶
↰ Return to documentation for file (include/nix/Variant.hpp)
// Copyright © 2015, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>
#ifndef NIX_VARIANT_H
#define NIX_VARIANT_H
#include <nix/DataType.hpp>
#include <nix/Platform.hpp>
#include <nix/None.hpp>
#include <string>
#include <cstdint>
#include <stdexcept>
#include <iostream>
namespace nix {
class NIXAPI Variant {
private:
DataType dtype;
union {
bool v_bool;
double v_double;
uint32_t v_uint32;
int32_t v_int32;
uint64_t v_uint64;
int64_t v_int64;
char *v_string;
};
public:
Variant() : dtype(DataType::Nothing), v_bool(false) { }
explicit Variant(char *value) : dtype(DataType::Nothing) {
set(value);
}
explicit Variant(const char *value) : dtype(DataType::Nothing) {
set(value);
}
template<typename T>
explicit Variant(const T &value) : dtype(DataType::Nothing) {
set(value);
}
template<size_t N>
explicit Variant(const char (&value)[N]) : dtype(DataType::Nothing) {
set(value, N);
}
Variant(const Variant &other) : Variant() {
assign_variant_from(other);
}
Variant(Variant &&other) NOEXCEPT : Variant() {
if (other.dtype == DataType::String) {
v_string = other.v_string;
dtype = DataType::String;
other.dtype = DataType::Nothing;
other.v_string = nullptr;
} else {
assign_variant_from(other);
}
}
Variant &operator=(Variant other) {
assign_variant_from(other);
return *this;
}
virtual ~Variant() {
maybe_deallocte_string();
}
void set(none_t);
void set(bool value);
void set(int32_t value);
void set(uint32_t value);
void set(int64_t value);
void set(uint64_t value);
void set(double value);
void set(const char *value, const size_t len);
void set(const char *value);
void set(const std::string &value);
template<typename T>
T get() const {
T temp;
get(temp);
return temp;
}
void get(none_t &tag) const;
void get(bool &out) const;
void get(int32_t &value) const;
void get(uint32_t &value) const;
void get(int64_t &value) const;
void get(uint64_t &value) const;
void get(double &value) const;
void get(std::string &value) const;
DataType type() const {
return dtype;
}
void swap(Variant &other);
static bool supports_type(DataType dtype);
private:
void assign_variant_from(const Variant &other);
void maybe_deallocte_string();
inline void check_argument_type(DataType check) const {
if (dtype != check) {
throw std::invalid_argument("Incompatible DataType");
}
}
};
template<>
inline const char *Variant::get<const char *>() const {
check_argument_type(DataType::String);
return v_string;
}
template<>
inline none_t Variant::get<none_t>() const {
return nix::none;
}
NIXAPI std::ostream &operator<<(std::ostream &out, const Variant &value);
NIXAPI bool operator==(const Variant &a, const Variant &b);
inline bool operator!=(const Variant &a, const Variant &b) { return !(a == b); }
NIXAPI void swap(Variant &a, Variant &b);
} // nix::
#endif