boost.any源码整理和使用说明

Source

#include <algorithm>

#include <typeinfo>

#include "boost/config.hpp"

#include <boost/type_traits/remove_reference.hpp>

#include <boost/type_traits/is_reference.hpp>

#include <boost/throw_exception.hpp>

#include <boost/static_assert.hpp>

namespace kimi_boost

{

class any

{

template<typename ValueType>

friend ValueType * any_cast(any *);

public:

//ctor

any() : content(0){}

//ctor: from a value of any type

template<typename ValueType>

any(const ValueType & value): content(new holder<ValueType>(value)){}

//copy-ctor: from another any object

any(const any & other): content(other.content ? other.content->clone() : 0){}

//dtor

~any(){delete content;}

//swap two any objects

any& swap(any & rhs)

{

std::swap(content, rhs.content);

return *this;

}

//assign from a value of any type

template<typename ValueType>

any & operator=(const ValueType & rhs)

{

any(rhs).swap(*this);

return *this;

}

//assign from another any object

any & operator=(const any & rhs)

{

any(rhs).swap(*this);

return *this;

}

bool empty() const {return !content;}

//get the type_info& using RTTI

const std::type_info & type() const

{

//see holder::type()

return content ? content->type() : typeid(void);

}

private:

//inner class

class placeholder

{

public:

virtual ~placeholder(){}

virtual const std::type_info & type() const = 0;

virtual placeholder * clone() const = 0;

};//class placeholder

template<typename ValueType>

class holder : public placeholder

{

public:

holder(const ValueType & value): held(value){}

virtual const std::type_info & type() const

{return typeid(ValueType);}

//note the return type is "placeholder*" rather than "holder*"

virtual placeholder * clone() const

{return new holder(held);}

//the real object of various type

ValueType held;

};//class holder

private://the only member data

placeholder* content;

};//class any

//an exception class that will be thrown when type cast fails

class bad_any_cast : public std::bad_cast

{

public:

virtual const char * what() const throw()

{return "boost::bad_any_cast: failed conversion using boost::any_cast";}

};

//两个指针版本的any_cast不会抛出异常,失败时返回

//any_cast functions are based on typeid and type_info

template<typename ValueType>

ValueType * any_cast(any * operand)

{

return ( operand && operand->type() == typeid(ValueType) )

? &static_cast<any::holder<ValueType> *>(operand->content)->held

: 0;

}

template<typename ValueType>

const ValueType * any_cast(const any * operand)

{

return any_cast<ValueType>(const_cast<any *>(operand));

}

//两个引用版本的any_cast失败时会抛出异常

template<typename ValueType>

ValueType any_cast(const any & operand)

{

typedef typename remove_reference<ValueType>::type nonref;

const nonref * result = any_cast<nonref>(&operand);

if(!result)

boost::throw_exception(bad_any_cast());

return *result;

}

template<typename ValueType>

ValueType any_cast(any & operand)

{

typedef typename remove_reference<ValueType>::type nonref;

nonref * result = any_cast<nonref>(&operand);

if(!result)

boost::throw_exception(bad_any_cast());

return *result;

}

}

Test code

bool is_empty(const kimi_boost::any & operand)

{

return operand.empty();

}

bool is_int(const kimi_boost::any & operand)

{

return operand.type() == typeid(int);

}

bool is_char_ptr(const kimi_boost::any & operand)

{

try

{

kimi_boost::any_cast<const char *>(operand);

return true;

}

catch(const kimi_boost::bad_any_cast &)

{

return false;

}

}

bool is_string(const kimi_boost::any & operand)

{

return kimi_boost::any_cast<std::string>(&operand);

}

void count_all(std::list<kimi_boost::any> & values, std::ostream & out)

{

out << "#empty == "

<< std::count_if(values.begin(), values.end(), is_empty) << std::endl;

out << "#int == "

<< std::count_if(values.begin(), values.end(), is_int) << std::endl;

out << "#const char * == "

<< std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl;

out << "#string == "

<< std::count_if(values.begin(), values.end(), is_string) << std::endl;

}

void any_test()

{

std::list<kimi_boost::any> la;

la.push_back(int(1));

la.push_back(double(1));

la.push_back(char(1));

la.push_back(float(1));

la.push_back(kimi_boost::any((char)3));//char type

la.push_back(kimi_boost::any((int)3));//int type

la.push_back(kimi_boost::any());//empty

la.push_back(kimi_boost::any());//empty

count_all(la,std::cout);

}

Output

#empty == 2

#int == 2

#const char * == 0

#string == 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值