/**
* @file Any.hpp
* @author The ARTIS Development Team
* See the AUTHORS or Authors.txt file
*/
/*
* ARTIS - the multimodeling and simulation environment
* This file is a part of the ARTIS environment
*
* Copyright (C) 2013-2019 ULCO http://www.univ-littoral.fr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef COMMON_ANY_HPP
#define COMMON_ANY_HPP
#include
#include
#include
#include
#include
namespace artis {
namespace common {
class Any {
private:
struct base {
virtual ~base() { }
virtual base* clone() const = 0;
};
template
struct data : base {
data(V T::* const& value)
:value_(value) { }
base* clone() const { return new data(*this); }
V T::* value_;
};
base* ptr_;
public:
Any()
:ptr_(nullptr) { }
template
Any(V T::* const& value)
: ptr_(new data(value)) { }
Any(Any const& other)
:ptr_(other.ptr_ ? other.ptr_->clone() : nullptr) { }
virtual ~Any() { if (ptr_) delete ptr_; }
void operator=(Any const& other) { Any(other).swap(*this); }
void swap(Any& other) { std::swap(ptr_, other.ptr_); }
template
V T::* get() const { return dynamic_cast < data* >(ptr_)->value_; }
bool is_null() const { return ptr_ == nullptr; }
template
void put(T* o, const V& value)
{
V T::* p = dynamic_cast * >(ptr_)->value_;
o->*(p) = value;
}
template
void restore(T* o, const common::Value& value)
{
if (value.is_type()) {
double v;
value(v);
put(o, v);
} else if (value.is_type()) {
unsigned int v;
value(v);
put(o, v);
} else if (value.is_type()) {
int v;
value(v);
put(o, v);
} else if (value.is_type()) {
bool v;
value(v);
put(o, v);
} else if (value.is_type >()) {
std::vector v;
value(v);
put(o, v);
} else if (value.is_type >()) {
std::vector v;
value(v);
put(o, v);
} else if (value.is_type >()) {
std::vector v;
value(v);
put(o, v);
} else if (value.is_type >()) {
std::vector v;
value(v);
put(o, v);
} else {
assert(false);
}
}
template
common::Value save(const T* o) const
{
if (ptr_) {
data* q_double =
dynamic_cast < data* >(ptr_);
if (q_double) {
return common::Value(o->*(q_double->value_));
} else {
data* q_uint =
dynamic_cast < data* >(ptr_);
if (q_uint) {
return common::Value(o->*(q_uint->value_));
} else {
data* q_int =
dynamic_cast < data* >(ptr_);
if (q_int) {
return common::Value(o->*(q_int->value_));
} else {
data* q_bool =
dynamic_cast < data* >(ptr_);
if (q_bool) {
return common::Value(o->*(q_bool->value_));
} else {
data >* q_double_v =
dynamic_cast < data >* >(ptr_);
if (q_double_v) {
return common::Value(o->*(q_double_v->value_));
} else {
data >* q_int_v =
dynamic_cast < data >* >(ptr_);
if (q_int_v) {
return common::Value(o->*(q_int_v->value_));
} else {
data >* q_bool_v =
dynamic_cast < data >* >(ptr_);
if (q_bool_v) {
return common::Value(
o->*(q_bool_v->value_));
}
}
}
}
}
}
}
}
assert(false);
return common::Value();
}
template
std::string to_string(const T* o) const
{
if (ptr_) {
data* q_double =
dynamic_cast < data* >(ptr_);
if (q_double) {
return std::to_string(o->*(q_double->value_));
} else {
data* q_uint =
dynamic_cast < data* >(ptr_);
if (q_uint) {
return std::to_string(o->*(q_uint->value_));
} else {
data* q_int =
dynamic_cast < data* >(ptr_);
if (q_int) {
return std::to_string(o->*(q_int->value_));
} else {
data* q_bool =
dynamic_cast < data* >(ptr_);
if (q_bool) {
return o->*(q_bool->value_) ? "true" : "false";
} else {
data >* q_double_v =
dynamic_cast < data >* >(ptr_);
if (q_double_v) {
return "";
} else {
data >* q_int_v =
dynamic_cast < data >* >(ptr_);
if (q_int_v) {
return "";
} else {
data >* q_bool_v =
dynamic_cast < data >* >(ptr_);
if (q_bool_v) {
return "";
} else {
return "NA";
}
}
}
}
}
}
}
} else {
return "NA";
}
}
};
}
}
#endif