C++11:借助std::tuple实现CSV的读写

本文介绍了如何使用C++11的std::tuple特性来实现CSV文件的读写操作,强调了接口设计的灵活性和通用性,不再依赖于boost库,实现了跨平台的一套代码解决方案。
摘要由CSDN通过智能技术生成

一直想写个CSV读写的模板,但是接口的定义一直是个问题。CSV每列都可以任意映射成C++基本类型,怎么把接口定义得既通用又灵活?最近发现C++11引入了tuple,接口也可以像python一样的方便漂亮,而且不再依赖boost库,真正做到Windows/Linux一套代码。


#ifndef _CSV_TO_TUPLES_H
#define _CSV_TO_TUPLES_H

#include <stdlib.h>
#include <string>
#include <istream>
#include <ostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <memory>
#include "common/common_utils.h"

namespace util {
namespace csv_tuple {


template <typename T>
class NullType
{
public:
    explicit NullType()
        : is_null(true) // by default, NULL value
    {}

    explicit NullType(const NullType& src)
        : is_null(src.is_null), value(src.value)
    {}

    explicit NullType(const T& v)
        : is_null(false), value(v)
    {}

    ~NullType()
    {}

    void Reset()
    {
        // not all types can be reset by assigning of 0
        *this = NullType();
    }

    NullType& operator=(const NullType& src)
    {
        this->is_null = src.is_null;
        this->value = src.value;
        return *this;
    }

public:
    bool is_null;
    T value;
};

typedef NullType<char> NullChar;
typedef NullType<unsigned char> NullUChar;
typedef NullType<short> NullShort;
typedef NullType<unsigned short> NullUShort;
typedef NullType<int> NullInt;
typedef NullType<unsigned int> NullUInt;
typedef NullType<long long> NullBigInt;
typedef NullType<unsigned long long> NullUBigInt;
typedef NullType<float> NullFloat;
typedef NullType<float> NullReal;
typedef NullType<double> NullDouble;

typedef NullType<bool> NullBool;
typedef NullType<std::string> NullString;


template <typename T>
void StringToValue(const std::string& str, NullType<T>& value)
{
    if (str.empty()) {
        value.Reset();
    }
    else {
        value.is_null = false;
        StringToValue(str, value.value);
    }
}

static inline void StringToValue(const std::string &str, char &value)
{
    value = (char)atoi(str.c_str());
}

static inline void StringToValue(const std::string &str, unsigned char &value)
{
    value = (unsigned char)atoi(str.c_str());
}

static inline void StringToValue(const std::string &str, short &value)
{
    value = (short)atoi(str.c_str());
}

static inline void StringToValue(const std::string &str, unsigned short &value)
{
    value = (unsigned short)atoi(str.c_str());
}

static inline void StringToValue(const std::string &str, int &value)
{
    value = atoi(str.c_str());
}

static inline void StringToValue(const std::string &str, unsigned int &value)
{
    value = (unsigned int)std::strtoul(str.c_str(), NULL, 10);
}

static inline void StringToValue(const std::string &str, long long &value)
{
#ifdef _WIN32
    value = _atoi64(str.c_str());
#else
    value = atoll(str.c_str());
#endif
}

static inline void StringToValue(const std::string &str, unsigned long long &value)
{
    value = (unsigned long long)std::strtoull(str.c_str(), NULL, 10);
}

static inline void StringToValue(const std::string &str, bool &value)
{
    value = atoi(str.c_str()) != 0;
}

static inline void StringToValue(const std::string& str, std::string& value)
{
    value = str;
}

static inline void StringToValue(const std::string& str, float& value)
{
    value = (float)atof(str.c_str());
}

static inline void StringToValue(const std::string& str, double& value)
{
    value = atof(str.c_str());
}

// add more versions of StringToValue() if needed


#define TUPLE_SET_ITEM(tp, i) \
    T##i t##i; \
    StringToValue(subs[i], t##i); \
    std::get<i>(tp) = t##i

template<typename T0>
void FillTuple(const std::vector<std::string>& subs,
    std::tuple<T0>& tp)
{
    TUPLE_SET_ITEM(tp, 0);
}

template<typename T0, typename T1>
void FillTuple(const std::vector<std::string>& subs,
    std::tuple<T0, T1>& tp)
{
    TUPLE_SET_ITEM(tp, 0);
    TUPLE_SET_ITEM(tp, 1);
}

template<typename T0, typename T1, typename T2>
void FillTuple(const std::vector<std::string>& subs,
    std::tuple<T0, T1, T2>& tp)
{
    TUPLE_SET_ITEM(tp, 0);
    TUPLE_SET_ITEM(tp, 1);
    TUPLE_SET_ITEM(tp, 2);
}

template<typename T0, typename T1, typename T2, typename T3>
void FillTuple(const std::vector<std::string>& subs,
    std::tuple<T0, T1, T2, T3>& tp)
{
    TUPLE_SET_ITEM(tp, 0);
    TUPLE_SET_ITEM(tp, 1);
    TUPLE_SET_ITEM(tp, 2);
    TUPLE_SET_ITEM(tp, 3);
}

template<typename T0, typename T1, typename T2, typename T3, typename T4>
void FillTuple(const std::vector<std::string>& subs,
    std::tuple<T0, T1, T2, T3, T4>& tp)
{
    TUPLE_SET_ITEM(tp, 0);
    TUPLE_SET_ITEM(tp, 1);
    TUPLE_SET_ITEM(tp, 2);
    TUPLE_SET_ITEM(tp, 3);
    TUPLE_SET_ITEM(tp, 4);
}

template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
void FillTuple(const std::vector<std::string>& subs,
    std::tuple<T0, T1, T2, T3, T4, T5>& tp)
{
    TUPLE_SET_ITEM(tp, 0);
    TUPLE_SET_ITEM(tp, 1);
    TUPLE_SET_ITEM(tp, 2);
    TUPLE_SET_ITEM(tp, 3);
    TUPLE_SET_ITEM(tp, 4);
    TUPLE_SET_ITEM(tp, 5);
}

template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
    typename T6>
    void FillTuple(const std::vec
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值