#include <iostream>
#include <type_traits>
#include <utility>
#include <vector>
#include <stdexcept>
#include <functional>
class Any {
public:
//notice this!
template<typename Ty>
using StorageType = typename std::decay<Ty>::type;
template<typename Ty, typename =
typename std::enable_if< !std::is_same<Any, StorageType<Ty>>::value
&& !std::is_same<Any*, StorageType<Ty>>::value>::type>
Any(Ty&& value) :container(new Container<StorageType<Ty>>(std::forward<Ty>(value)))
{
std::cout<< "constructor" <<std::endl;
}
Any(const Any& other)
{
if (this->container != nullptr) {
delete (this->container);
this->container = other.clone();
}else {
this->container = other.clone();
}
}
Any(Any&& other)
{
if (this->container != nullptr) {
delete (this->container);
this->container = other.container;
}else {
this->container = other.container;
}
other.container = nullptr;
}
Any& operator=(Any&& other)
{
if (this->container == nullptr) {
this->container = other.container;
}else {
delete (this->container);
this->container = other.container;
}
other.container = nullptr;
}
Any& operator=(const Any& other)
{
if (this->container != nullptr) {
delete (this->container);
(this->container) = other.clone();
}else {
(this->container) = other.clone();
}
return *this;
}
Any() :container(nullptr) {}
~Any()
{
if (container != nullptr)
{
delete container;
(this->container) = nullptr;
}
}
/*
template<typename Ty>
Ty getValue()const noexcept
{
if ((this->container) == nullptr) {
std::runtime_error("There is nothing!");
}
Container<StorageType<Ty>>* derived = dynamic_cast<Container<StorageType<Ty>>*>(this->container);
return (derived->data);
}*/
template<typename Ty>
Ty getValue()
{
if ((this->container) == nullptr) {
std::runtime_error("There is nothing!");
}
std::cout << "test" <<std::endl;
Container<Ty>* derived = dynamic_cast<Container<Ty>*>(this->container);
std::cout << "derived-data: " << derived->data << std::endl;
return (derived->data);
}
/*
template<typename Ty>
operator Ty&()
{
/*auto*/
//std::function<Ty& ()const noexcept> function = static_cast<Ty& (Any::*)()const noexcept>(&Any::getValue);
//Cotainer<StorageType<Ty>>* contain = dynamic_cast<Container<StorageType<Ty>>*>(this->container);
//return (contain->data);
//}
/*template<typename Ty>
operator Ty()const
{
std::function<Ty()noexcept> function = static_cast<Ty(Any::*)()noexcept>(&Any::getValue);
return (this->*function());
}*/
private:
class ContainerBase {
public:
ContainerBase() = default;
ContainerBase(const ContainerBase& ) = default;
ContainerBase(ContainerBase&& ) = default;
ContainerBase& operator=(const ContainerBase& )=default;
ContainerBase& operator=(ContainerBase&& )=default;
virtual ~ContainerBase() = default;
virtual ContainerBase* clone()const noexcept = 0; //pure-virtual function.
};
template<typename Type>
class Container : public ContainerBase {
public:
Type data;
Container(Type&& value_) :ContainerBase(),data(value_) {}
Container(const Type& value_) :ContainerBase(),data(value_) {}
Container(const Container<Type>& other):ContainerBase(other),data(other.data){}
Container(Container<Type>&& other):ContainerBase(other),data(std::move(other.data)){}
Container& operator=(const Container<Type>& other)
{
ContainerBase::operator=(other);
this->data = other.data;
}
Container& operator=(Container<Type>&& other)
{
ContainerBase::operator=(other);
this->data = other.data;
}
virtual ~Container() = default;
virtual ContainerBase* clone()const noexcept override
{
return (new Container<StorageType<Type>>(this->data));
}
};
ContainerBase* clone()const noexcept
{
if (this->container == nullptr) {
return nullptr;
}else {
return (this->container)->clone();
}
}
ContainerBase* container;
};
class Eplace_back {
public:
Eplace_back() = default;
~Eplace_back() = default;
Eplace_back(const Eplace_back& other) = delete;
Eplace_back& operator=(const Eplace_back& other) = delete;
template<typename Ty>
void operator()(std::vector<Any>& vec, Ty&& value)
{
std::cout << "pus value in vector" << std::endl;
vec.emplace_back(std::forward<Ty>(value));
}
};
int main()
{
std::vector<Any> myVector;
Eplace_back emplace_back;
emplace_back(myVector, 100);
emplace_back(myVector, 200);
std::cout << myVector[0].getValue<int>() << std::endl;
std::cout << myVector[1].getValue<int>() << std::endl;
std::cout<< "xxxxxxxxxxxx" <<std::endl;
return 0;
}