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

 

原创粉丝点击