|

楼主 |
发表于 2020-1-15 16:46:46
|
显示全部楼层
variant_sruct.h
- //=======================================================================================
- //--------------------------------------------------------------------------------------|
- // variant类的框架,不含Data部分 |
- //--------------------------------------------------------------------------------------|
- //=======================================================================================
- #ifndef __VARIANT_STRUCT_H
- #define __VARIANT_STRUCT_H
- #include <share.h>
- #include <iostream>
- #include <initializer_list>
- #include <string>
- #include <vector>
- #include <assert.h>
- #include "variant_meta.h"
- namespace croper {
- //================================================================================
- //定义开始
- //===============================================================================
- class variant {
- private:
- using string = std::string;
- public:
- using list = std::vector<variant>;
- static const variant None;
- #ifndef VARIANT_REGISTER_TYPE
- #define VARIANT_REGISTER_TYPE
- #endif
- //****************************************************************************
- //==================================================================================
- //IData类,定义Data的接口
- //==================================================================================
- struct IData {
- public:
- //自身的类型
- virtual std::string mytype() const = 0;
- //转化为字符串,对于于__str__方法
- virtual std::string to_string() const = 0;
- //返回自身的拷贝
- virtual IData* copy() const = 0;
- //以类型T获取数据,会发生类型的默认转化,当类型不匹配时会给出默认值,如果定义了宏VARIANT_STRICT_TYPE_CHECK的话会报错
- template <typename T> T get_data();
- //以类型T获取数据,会发生类型的默认转化
- template <typename T> void trans_type(variant*);
- //原始数据:类型指定错误会错误
- template <typename T> T& original_data();
- //*******************************宏代码块***************************************
- //get_data与astype是模板,本身无法继承,这里让get_data调用_get_data_int,_get_data_float等以实现继承
- #define VARIANT_REGISTER(T) \
- virtual T _get_data_##T##() = 0;\
- virtual void _trans_type_##T##(variant*) = 0;\
- template<> T get_data<T>(){\
- return _get_data_##T##();\
- }\
- template<> void trans_type<T>(variant* base) {\
- _trans_type_##T##(base);\
- }
- VARIANT_REGISTER_TYPE;
- #undef VARIANT_REGISTER
- //****************************************************************************
- };
- //声明为友元
- friend struct IData;
- //创建Data,解耦合用
- template <typename T>
- static std::shared_ptr<IData> CreateData();
- template <typename T>
- static std::shared_ptr<IData> CreateData(const T& t);
- //========================================================================================
- //Judge类,技术类,根据不同的模板参数给出不同的函数
- //========================================================================================
- template <int N, typename T, typename my_type, typename templ_arg>
- struct Judge;
- //Judge<0>
- template <typename T, typename my_type, typename templ_arg>
- struct Judge<0, T, my_type, templ_arg> {
- static T get_data(my_type*);
- static void transtype(my_type*, variant*);
- };
- //Judge<1>
- template <typename T, typename my_type, typename templ_arg>
- struct Judge<1, T, my_type, templ_arg> {
- static T get_data(my_type* self);
- static void transtype(my_type*, variant*);
- };
- //Judge<2>
- template <typename T, typename my_type, typename templ_arg>
- struct Judge<2, T, my_type, templ_arg> {
- static void transtype(my_type*, variant*);
- };
- //Judge<3>
- template <typename T, typename my_type, typename templ_arg>
- struct Judge<3, T, my_type, templ_arg> {
- static void transtype(my_type*, variant*);
- };
- //Judge<4>
- template <typename T, typename my_type, typename templ_arg>
- struct Judge<4, T, my_type, templ_arg> {
- static void transtype(my_type*, variant*);
- };
- //========================================================================================
- //DistinguishType类,技术类,当两type相同时返回0,第一个是list时返回1,第二个是list时返回2,能转化时返回3,不能转化时返回4
- //========================================================================================
- public:
- template <typename Dest, typename Orig>
- struct DistinguishType {
- public:
- enum { result = 4 - CanMatch<Dest, Orig>::result };
- };
- template <typename T>
- struct DistinguishType<T, T> {
- enum { result = 0 };
- };
- template <typename T>
- struct DistinguishType<list, T> {
- enum { result = 1 };
- };
- template <typename T>
- struct DistinguishType<T, list> {
- enum { result = 2 };
- };
- template <>
- struct DistinguishType<list, list> {
- enum { result = 0 };
- };
- //========================================================================================
- //_IData_templ类,技术类
- //模板分离后的IData,使分离的_get_data_int,_get_data_double等都指向同一个get_data,并使用Judge判断其类型是否匹配,
- //不匹配时,其将指向一个报错的函数
- //如果使用if语句会导致虽然这一块永远不会执行但是无法通过编译。
- //========================================================================================
- template <typename templ_arg>
- struct _IData_templ :public IData {
- virtual templ_arg& get_data() = 0;
- //*******************************宏代码块***************************************
- #define VARIANT_REGISTER(T) \
- virtual T _get_data_##T##() override{\
- return Judge<CanMatch<T,templ_arg>::result,T,_IData_templ,templ_arg>::get_data(this);\
- }\
- virtual void _trans_type_##T##(variant* base) override{\
- constexpr int d=DistinguishType<T,templ_arg>::result;\
- Judge<d, T, _IData_templ, templ_arg>::transtype(this,base);\
- }
- VARIANT_REGISTER_TYPE;
- #undef VARIANT_REGISTER
- //****************************************************************************
- };
- //=====================================================================
- //variant类自身的函数
- //=====================================================================
- private:
- //使用智能指针指向_data,这样不再需要对_data进行内存管理,且能进行浅拷贝。
- //python变量也是相似的机制
- std::shared_ptr<IData> _data;
- //====================================================================
- public:
- //构造函数
- variant();
- //根据原始数据构造
- template <typename T> variant(const T& t);
- //根据多个原始数据构造出列表
- variant(const std::initializer_list<variant>&);
- template <typename ...T> variant(const T&... t);
- //复制构造函数,不需要,直接浅复制即可
- variant(const variant&) = default;
- //析构函数,不需要
- ~variant() = default;
- //以字符串形式输出Data的类型
- std::string type() const;
- //Data是否是某种特定类型
- template <typename T>bool is_type() const;
- //将Data转化为某种特定类型,如果不兼容会转化为空值
- template <typename T>variant& set_type();
- //将自身重置为None
- void clear();
- //转化为字符串:
- std::string to_string() const;
- //将自身解包为参数传入function
- template <typename retT, typename ...TArgs> retT call(retT(*fp)(TArgs...));
- //将自身解包为参数传入function,返回值为void的重载版本
- template <typename ...TArgs> void call(void(*fp)(TArgs...));
- //当自身为list时于尾部插入一个元素。
- void append(const variant&);
- //当自身为list时获得list的大小
- size_t size() const;
- //当自身为list时返回尾部元素
- variant& back();
- //赋值函数
- template <typename T> variant& operator=(const T&);
- //赋值函数,std::vector重载版本
- template <typename T> variant& operator=(const std::vector<T>&);
- //赋值函数,const char*重载版本,以接受字面常量
- variant& operator=(const char* sz);
- //复制构造函数,不需要重写
- variant& operator=(const variant& v) = default;
- //转化为特定类型
- template <typename T> operator T() const;
- //转化为特定类型,std::vector重载版本
- template <typename T> operator std::vector<T>() const;
- //获取原始数据,慎用
- template <typename T> T& __My_base();
- template <typename T> const T& __My_base() const;
- //================================以下是各种运算符的重载==============================
- //已完成部分
- //重载<<实现输出
- friend std::ostream& operator<<(std::ostream& os, const variant&);
- //重载[]
- variant& operator[](int i);
- //const版本
- const variant& operator[](int i) const;
- //未完成部分
- //工作量有点大,有时间慢慢写
- bool operator==(const variant&);
- template <typename T> bool operator==(const T&);
- //template <typename T> bool friend operator== (const T&, const variant&);
- bool operator!=(const variant&);
- template <typename T> bool operator!=(const T&);
- //template <typename T> bool friend operator!=(const T&, const variant&);
- variant& operator++();
- variant& operator--();
- variant operator++(int);
- variant operator--(int);
- variant& operator+ (const variant&);
- template <typename T> variant& operator+(const T&);
- template <typename T> friend variant& operator+(const T&, const variant&);
- variant& operator+=(const variant&);
- template <typename T> variant& operator+= (const T&);
- variant& operator- (const variant&);
- template <typename T> variant& operator-(const T&);
- template <typename T> friend variant& operator-(const T&, const variant&);
- variant& operator-=(const variant&);
- template <typename T> variant& operator-=(const T&);
- variant& operator* (const variant&);
- template <typename T> variant& operator*(const T&);
- template <typename T> friend variant& operator*(const T&, const variant&);
- variant& operator*=(const variant&);
- template <typename T> variant& operator*=(const T&);
- variant& operator/ (const variant&);
- template <typename T> variant& operator/(const T&);
- template <typename T> friend variant& operator/(const T&, const variant&);
- variant& operator/=(const variant&);
- template <typename T> variant& operator/=(const T&);
- variant& operator% (const variant&);
- template <typename T> variant& operator%(const T&);
- template <typename T> friend variant& operator%(const T&, const variant&);
- variant& operator%=(const variant&);
- template <typename T> variant& operator%=(const T&);
- };
- //=============================================================================
- //以下是周边函数的声明
- //=============================================================================
- //错误信息,debug模式下输出错误信息,release模式下直接抛出异常
- void ErrorMsg(std::string s);
- //由字符串转化为variant,特色功能
- variant Variant_Read(const std::string&);
- //可以在字符串后加_V以简化实现上述功能
- variant operator ""_V(const char* p, size_t s);
- //=============================================================================
- //声明结束,以下是模板函数的实现代码
- //=============================================================================
- //------------------------------------------------------------------------
- //IData类的函数
- //-------------------------------------------------------------------------
- //原始数据:类型指定错误会错误
- template<typename T>
- inline T & variant::IData::original_data()
- {
- return dynamic_cast<_IData_templ<T>*>(this)->get_data();
- }
-
- //----------------------------------------------------------------------------
- //Judge类的函数
- //----------------------------------------------------------------------------
- //当原类型与目标类型相同时
- template<typename T, typename my_type, typename templ_arg>
- inline void variant::Judge<0, T, my_type, templ_arg>::transtype(my_type * self, variant * base)
- {
- //什么也不做
- }
- //当目标类型为list但源类型不为list时,转化为长度为1的list,第一个元素即为自身
- template<typename T, typename my_type, typename templ_arg>
- inline void variant::Judge<1, T, my_type, templ_arg>::transtype(my_type * self, variant * base)
- {
- base->_data = CreateData<list>(list({ *base }));
- }
- //当目标类型不为list但源类型为list时,将第一个元素转化为目标元素
- template<typename T, typename my_type, typename templ_arg>
- inline void variant::Judge<2, T, my_type, templ_arg>::transtype(my_type * self, variant * base)
- {
- *base = base[0];
- base->set_type<T>();
- }
- //当源类型能转化为目标类型时,进行默认转化
- template<typename T, typename my_type, typename templ_arg>
- inline void variant::Judge<3, T, my_type, templ_arg>::transtype(my_type * self, variant * base)
- {
- base->_data = CreateData<T>(self->get_data());
- }
- //当源类型不能转化为目标类型时,设为默认值
- template<typename T, typename my_type, typename templ_arg>
- inline void variant::Judge<4, T, my_type, templ_arg>::transtype(my_type * self, variant * base)
- {
- base->_data = CreateData<T>(T());
- }
- template<typename T, typename my_type, typename templ_arg>
- inline T variant::Judge<1, T, my_type, templ_arg>::get_data(my_type * self) {
- return static_cast<T>(self->get_data());
- }
- template<typename T, typename my_type, typename templ_arg>
- inline T variant::Judge<0, T, my_type, templ_arg>::get_data(my_type * self) {
- #ifdef VARIANT_STRICT_TYPE_CHECK
- std::string s = std::string(typeid(T).name()) + "与" + typeid(templ_arg).name() + "的类型无法匹配";
- ErrorMsg(s);
- #endif
- return T();
- }
- //------------------------------------------------------------------------------------
- //variant自身的函数
- //----------------------------------------------------------------------------------------
- template<typename T>
- inline variant::variant(const T & t) {
- operator=(t);
- }
- template<typename T>
- inline bool variant::is_type() const
- {
- IData *p = &*_data;
- return dynamic_cast<_IData_templ <T>*>(p) != nullptr;
- }
-
- template<>
- inline bool variant::is_type<void>() const {
- return !_data;
- }
- template<typename T>
- inline variant & variant::set_type()
- {
- if (!_data) {
- _data = CreateData<T>();
- }
- _data->trans_type<T>(this);
- return *this;
- }
- template<typename ...TArgs>
- struct SendArgs {
- template <typename retT, typename T>
- static retT call(retT(*fp)(TArgs..., T), variant lst_v, int i, TArgs...args) {
- return fp(args..., lst_v[i]);
- }
- template <typename retT, typename T>
- static retT call(retT(*fp)(TArgs..., T&), variant lst_v, int i, TArgs...args) {
- return fp(args..., lst_v[i].__My_base<T>());
- }
- template <typename retT, typename T, typename ...TArgs2>
- static retT call(retT(*fp)(TArgs..., T, TArgs2...), variant lst_v, int i, TArgs...args) {
- return SendArgs<TArgs..., T>::call(fp, lst_v, i + 1, args..., lst_v[i]);
- }
- template <typename retT, typename T, typename ...TArgs2>
- static retT call(retT(*fp)(TArgs..., T&, TArgs2...), variant lst_v, int i, TArgs...args) {
- return SendArgs<TArgs..., T&>::call(fp, lst_v, i + 1, args..., lst_v[i].__My_base<T>());
- }
- template <typename T>
- static void call(void(*fp)(TArgs..., T), variant lst_v, int i, TArgs...args) {
- fp(args..., lst_v[i]);
- }
- template <typename T>
- static void call(void(*fp)(TArgs..., T&), variant lst_v, int i, TArgs...args) {
- fp(args..., lst_v[i].__My_base<T>());
- }
- template < typename T, typename ...TArgs2>
- static void call(void(*fp)(TArgs..., T, TArgs2...), variant lst_v, int i, TArgs...args) {
- SendArgs<TArgs..., T>::call(fp, lst_v, i + 1, args..., lst_v[i]);
- }
- template < typename T, typename ...TArgs2>
- static void call(void(*fp)(TArgs..., T&, TArgs2...), variant lst_v, int i, TArgs...args) {
- SendArgs<TArgs..., T&>::call(fp, lst_v, i + 1, args..., lst_v[i].__My_base<T>());
- }
- };
- template<typename retT, typename ...TArgs>
- inline retT variant::call(retT(*fp)(TArgs...))
- {
- variant temp = *this;
- temp.set_type<list>();
- list l = temp._data->original_data<list>();
- return SendArgs<>::call(fp, temp, 0);
- }
- template<typename ...TArgs>
- inline void variant::call(void(*fp)(TArgs...))
- {
- variant temp = *this;
- temp.set_type<list>();
- list l = temp._data->original_data<list>();
- SendArgs<>::call(fp, temp, 0);
- }
- template<typename T>
- variant & variant::operator=(const T & t)
- {
- _data = CreateData<T>(t);
- return *this;
- }
- //赋值函数
- //当右值为std::vector时,类型统一为list(std::vector<variant>)
- template<typename T>
- inline variant & variant::operator=(const std::vector<T>& v)
- {
- _data = CreateData<list>(v);
- return *this;
- }
- template<typename T>
- inline variant::operator T() const
- {
- if (_data == nullptr) {
- return T();
- }
- return _data->get_data<T>();
- }
- template<typename T>
- inline T & variant::__My_base()
- {
- assert(is_type<T>());
- return _data->original_data<T>();
- }
- template<typename T>
- inline const T & variant::__My_base() const
- {
- assert(is_type<T>());
- return _data->original_data<T>();
- }
- template<typename T>
- inline variant::operator std::vector<T>() const
- {
- if (!is_type<list>()) {
- ErrorMsg("variant不是list类型,无法转化为std::vector");
- return std::vector<T>();
- }
- std::vector<T> ret;
- for (int i = 0; i < this->size(); ++i) {
- ret.push_back(this->operator[](i));
- }
- return ret;
- }
- };
- #endif
复制代码 |
|