boost.any源码整理和使用说明
来源:互联网 发布:淘宝店名如何修改 编辑:程序博客网 时间:2024/05/07 12:18
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
- boost.any源码整理和使用说明
- boost.pool源码整理和使用说明
- boost.array源码整理和使用说明
- boost.BOOST_STATIC_ASSERT源码整理和使用说明
- boost.shared_ptr源码整理和使用说明
- boost.lexical_cast源码整理和使用说明
- boost.type_traits源码整理和使用说明(1)
- boost.tuple源码整理和使用说明
- Boost.Any 源码解析
- boost源码剖析之any
- boost之any源码解析
- 关于boost::any源码的额外解析
- boost::any
- Boost::any
- BOOST--any
- boost::any
- boost::any
- Boost::Any
- 微可
- Fedore Core 7硬盘安装, FC7硬盘安装,硬盘安装小结
- 使用Vs2005打造简单分页浏览器
- JavaScript 学习--二级联动菜单实现
- 起名程序开发
- boost.any源码整理和使用说明
- boost.array源码整理和使用说明
- 啊
- 利用servlet生成简单的验证码
- boost.BOOST_STATIC_ASSERT源码整理和使用说明
- boost.shared_ptr源码整理和使用说明
- JSP的九个隐含对象
- boost.lexical_cast源码整理和使用说明
- 送弟弟阿亮回家