发一个刷leetcode时突发奇想弄出来的玩意:仿python的variant变量。
一直用c++在刷leetcode,但leetcode上的测试数据都是python格式的,调试起来很不方便。最先是想要弄一个翻译器,把python格式的测试数据翻译成c++ stl能支持的。。。然后越弄越奇怪,就弄出了这么一个玩意儿,算是仿冒python的变量类型把:
源代码发在楼下,先发个说明,算是文档吧- -#include<vector>
#include "variant.h"//include头文件
using namespace std;
using namespace croper;//variant定义在croper命名空间下
int Test1(int, vector<string>);
void Swap(int& a, int& b);
int main() {
cout << "================================================================================================" << endl;
cout << "1、能接受并输出多种类型的变量,现在支持int,double,bool,string,以及vector 5种类型。" << endl;
cout << "================================================================================================" << endl;
variant a = 5; //int
variant b = 4.99; //double
variant c = "hello world"; //string
variant d = false; //bool
variant o;
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
cout << o << endl;
cout << "================================================================================================" << endl;
cout << " 2、其中vector特化为python里的list类型,能容纳各种数据类型(其实就是vector<variant>)" << endl;
cout << "================================================================================================" << endl;
variant e = { 5,4.99,false,"hello world" }; //同时容纳多种数据类型
variant f = { {"there","is","no"},12315,"bigbang" }; //支持嵌套的初始化
cout << e << endl;
cout << f << endl;
f.append(e); //可以继续添加元素
e.append(f); //出现环路也可以正确识别
cout << f << endl;
cout << "================================================================================================" << endl;
cout << " 3、可以使用字符串初始化(这其实是最初的目的) " << endl;
cout << "================================================================================================" << endl;
variant s1 = Variant_Read("5,Bob,false,,,"); //使用字符串初始化
variant s2 = "5,3,9,,,"_V; //更加简单的写法
cout << s1 << endl;
cout << s2 << endl;
cout << "================================================================================================" << endl;
cout << " 4、可以将自身展开并传递给特定函数: " << endl;
cout << "================================================================================================" << endl;
variant r1 = R"(5,["Allice","Bob","Carol","Dave"])"_V;
int x = r1.call(Test1); //将r1展开传递给test1
cout << "返回值为" << x << endl;
cout << endl;
variant r2 = { 5,2 };
cout << "调用前r2为" << r2 << endl;
r2.call(Swap); //将r2展开传递给Swap,Swap将交换两个参数的值,这将正确反映到r2上
cout << "调用后r2为" << r2 << endl;
cout << "================================================================================================" << endl;
cout << " 5、大部分运算符重载工作未完工,dict类型尚未完成,敬请期待 " << endl;
cout << "================================================================================================" << endl;
system("pause");
}
int Test1(int n, vector<string> v) {
int ret = 0;
for (auto s : v) {
ret += s.size();
for (int i = 0; i < n; ++i) {
cout << s << endl;
}
cout << endl;
}
return ret;
}
void Swap(int& a, int& b) {
int t = a;
a = b;
b = t;
}
.h文件分为4部分
1、variant_meta.h#ifndef __VARIANT_META_H
#define __VARIANT_META_H
//variant需要用到的某些元编程模块
//检测两个类型是否相同
template<typename T1, typename T2>
class IsSame {
private:
enum { result = 0};
};
template<typename T>
class IsSame<T,T> {
private:
enum { result = 1 };
};
//检测两个类型是否能互相转化
template<typename Dest, typename Orig>
class CanMatch{
private:
static char Test(Dest);
static int Test(...);
static Orig MakeOrig();
public:
#pragma warning(disable:4244)
enum { result = sizeof(Test(MakeOrig())) == sizeof(char) };
#pragma warning(default:4244)
};
//检测某个类型是否是引用
template<typename T>
struct isReference{
enum { result = 0};
};
template<typename T>
struct isReference<T&> {
enum { result = 1 };
};
template<typename T>
struct isReference<T&&> {
enum { result = 1 };
};
#define IF_0(Code)
#define IF_1(Code) Code
#define IF(Bool,Code) IF_##Bool##(Code)
#endif 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;
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);
}
template <typename retT, typename T>
static retT call(retT(*fp)(TArgs..., T&), variant lst_v, int i, TArgs...args) {
return fp(args..., lst_v.__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);
}
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.__My_base<T>());
}
template <typename T>
static void call(void(*fp)(TArgs..., T), variant lst_v, int i, TArgs...args) {
fp(args..., lst_v);
}
template <typename T>
static void call(void(*fp)(TArgs..., T&), variant lst_v, int i, TArgs...args) {
fp(args..., lst_v.__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);
}
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.__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 3.variant_data.h#ifndef __VARIANT_DATA_H
#define __VARIANT_DATA_H
#include <string>
#include <vector>
#include <unordered_map>
#include <stack>
#include "variant.h"
namespace croper {
template <typename T>
class Data :public variant::_IData_templ<T> {
public:
T data;
Data() {};
Data(const T& t) :data(t) {};
T& get_data() override;
std::string mytype() const override;
Data* copy() const override;
std::string to_string() const override;
};
template<typename T>
inline T& Data<T>::get_data() {
return data;
}
template<typename T>
inline std::string Data<T>::mytype() const {
return typeid(data).name();
}
template<>
inline std::string Data<std::string>::mytype() const {
return "string";
}
template<>
inline std::string Data<variant::list>::mytype() const {
return "list";
}
template<typename T>
inline Data<T> * Data<T>::copy() const {
return new Data(*this);
}
template<typename T>
inline std::string Data<T>::to_string() const {
return std::to_string(data);
}
template <>
inline std::string Data<std::string>::to_string() const {
return data;
}
template <>
inline std::string Data<bool>::to_string() const {
return data ? "(true)" : "(false)";
}
//使用图的dps算法来构造当data的type为list时的字符串算法
//不能使用树的dps算法,可能会有环路。
template <>
inline std::string Data<std::vector<variant>>::to_string() const {
using list = variant::list;
struct ele {
const list* p;
int index;
};
struct map_ele {
int state;
std::string sz;
map_ele() :state(0), sz("") {};
};
std::unordered_map<const list*,map_ele> checked;
std::stack<ele> stk;
const list* p = &data;
stk.push({ p,0 });
checked.sz = "[";
while (!stk.empty()) {
checked.state = 1;
int &i = stk.top().index;
do {
std::string& sz = checked.sz;
const variant& v = (*p);
if (!v.is_type<list>()) {
sz += v.to_string();
sz += ",";
}
else {
map_ele& e = checked[&v.__My_base<list>()];
if (e.state == 2) {
sz += e.sz;
sz += ',';
}
else if (e.state == 1) {
sz += "[...]";
sz += ',';
}
else
{
p = &v.__My_base<list>();
stk.push({ p,0 });
checked.sz = "[";
break;
}
}
} while (++i < p->size());
while (stk.top().index == p->size()) {
if (p->empty()) {
checked.sz.push_back(']');
}
else {
checked.sz.back() = ']';
}
checked.state = 2;
std::string& sz = checked.sz;
stk.pop();
if (stk.empty()) break;
p = stk.top().p;
checked.sz += sz;
checked.sz +=',';
stk.top().index++;
}
}
return checked[&data].sz;
}
template <typename T>
inline std::shared_ptr<variant::IData> variant::CreateData() {
return std::make_shared<Data<T>>();
}
template <typename T>
inline std::shared_ptr<variant::IData> variant::CreateData(const T& t) {
return std::make_shared<Data<T>>(t);
}
};
#endif 4、variant.h 使用时包含这个就好//=======================================================================================
//--------------------------------------------------------------------------------------|
//variant类 |
//Created by Croper |
//last modified at Jan.15 2020 |
//仿python变量的变体类。 |
//主要分为两部分 Variant和Data |
//variant本身是一个智能指针的包装,作为表层数据,指向Data |
//Data是一个实际类型的包装,本身是模板,共同拥有一个接口IData |
//--------------------------------------------------------------------------------------|
//========================================================================================
#ifndef __VARIANT_H
#define __VARIANT_H
#ifndef VARIANT_REGISTER_TYPE
#define VARIANT_REGISTER_TYPE \
VARIANT_REGISTER(int)\
VARIANT_REGISTER(double)\
VARIANT_REGISTER(bool)\
VARIANT_REGISTER(string)\
VARIANT_REGISTER(list)
#endif
#include "variant_meta.h"
#include "variant_struct.h"
#include "variant_data.h"
#endif 然后还有一个variant.cpp
#include <sstream>
#include <stack>
#include <string>
#include "variant.h"
using namespace std;
namespace croper {
const variant variant::None = variant();
using list = variant::list;
void ErrorMsg(string s)
{
#ifdef _DEBUG
cerr << s << endl;
#else
throw "s";
#endif
}
ostream & operator<<(ostream & os, const variant &t)
{
if (t._data == nullptr) {
os << "(None)";
return os;
}
os << t._data->to_string();
return os;
}
//========================================================================================
//以下是variant的函数
//构造函数
variant::variant() {};
variant::variant(const initializer_list<variant>& l)
{
set_type<list>();
for (auto v : l) {
append(v);
}
}
variant Variant_Read_Simple(string& sz, int digit_type) {
variant v0;
if (sz.empty()) {
return v0;
}
else if (digit_type == 0) {
stringstream ss(sz);
int i;
ss >> i;
v0 = i;
}
else if (digit_type == 1) {
stringstream ss(sz);
double d;
ss >> d;
v0 = d;
}
else if (digit_type == 2) {
if (sz == "true" || sz == "True") {
v0 = true;
}
else if (sz == "false" || sz == "False") {
v0 = false;
}
else {
if (sz.size() >= 2 && sz == sz.back() && (sz == '\'' || sz == '\"')) {
sz = sz.substr(1, sz.size() - 2);
}
v0 = sz;
}
}
return v0;
}
variant Variant_Read(const string& sz)
{
variant ret;
stack<variant*> stk;
stk.push(&ret);
bool Recording = false; //是否正在记录
int digit_type = 0; //0为整数,1为浮点数,2为字符串
bool transfered = false; //转义标签,上一个字符串是否为转义符。
string temp;
ret.set_type<list>();
for (const char* p = sz.c_str();; p++) {
const char& c = *p;
variant& v = *stk.top();
if (Recording && c == '\0' || !transfered && c == ',' || Recording && !transfered && (c == '[' || c == ']')) {//结算当前字符串
variant v0= Variant_Read_Simple(temp,digit_type);
v.append(v0);
Recording = false;
if (*p == ',') {
continue;
}
}
if (!transfered && *p == '[') {
v.append(variant());
v.back().set_type<list>();
stk.push(&v.back());
continue;
}
else if (!transfered && *p == ']') {
stk.pop();
if (stk.empty()) {
break;
}
continue;
}
else if (!transfered && !Recording && (*p == ' ' || *p == '\n' || *p == '\t')) {
continue;
}
else if (*p == '\0') {
break;
}
else {
if (!transfered && *p == '//') {
transfered = true;
continue;
}
if (!Recording) {
Recording = true;
digit_type = 0;
temp.clear();
}
while (digit_type < 2) {
if (!isdigit(*p) && *p != '-' && *p != '.') {
digit_type = 2;
break;
}
if (*p == '-' && !temp.empty()) {
digit_type = 2;
break;
}
if (*p == '.') {
digit_type += 1;
break;
}
break;
}
temp.push_back(*p);
}
}
if (ret.size() == 0) {
return variant();
}
else if (ret.size() == 1) {
return ret;
}
return ret;
}
void variant::clear()
{
_data = nullptr;
}
string variant::to_string() const
{
if (_data == nullptr) {
return "(None)";
}
return _data->to_string();
}
void variant::append(const variant & v)
{
if (!is_type<list>()) {
ErrorMsg("错误:variant的类型不是list,无法使用append方法");
return;
}
_data->original_data<list>().push_back(v);
}
size_t variant::size() const
{
if (!is_type<list>()) {
ErrorMsg("错误:variant的类型不是list,无法使用size方法");
return -1;
}
return _data->original_data<list>().size();
}
variant& variant::back()
{
if (!is_type<list>()) {
ErrorMsg("错误:variant的类型不是list,无法使用back方法");
return *this;
}
return _data->original_data<list>().back();
}
variant & variant::operator=(const char * sz)
{
_data = CreateData<string>(sz);
return *this;
}
variant & variant::operator[](int i)
{
if (is_type<list>()) {
return _data->original_data<list>();
}
#ifdef VARIANT_REGISTER_TYPE
ErrorMsg("variant的内部类型不是list");
#endif
return *this;
}
const variant & variant::operator[](int i) const
{
if (is_type<list>()) {
return _data->original_data<list>();
}
#ifdef VARIANT_REGISTER_TYPE
ErrorMsg("variant的内部类型不是list");
#endif
return *this;
}
bool variant::operator==(const variant & v2)
{
if (_data == v2._data) return true;
return false;
}
string variant::type() const
{
if (_data == nullptr) {
return "void";
}
return _data->mytype();
}
variant operator ""_V(const char* p, size_t s) {
return Variant_Read(p);
}
} 用途嘛。。最初时拿来刷leetcode的题。。。。
现在看来把运算符完善了能搞一些泛型编程,
有兴趣的也可以吐槽下代码,欢迎发表批评,建议,感叹什么的。。
另附github地址
页:
[1]