C++11实现的Boost库中的Any类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11实现的Boost库中的Any类相关的知识,希望对你有一定的参考价值。

参考技术A /******************************************************************************

*

*  Permission is hereby granted, free of charge, to any person obtaining a copy

*  of this software and associated documentation files (the "Software"), to deal

*  in the Software without restriction, including without limitation the rights

*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

*  copies of the Software, and to permit persons to whom the Software is

*  furnished to do so, subject to the following conditions:

*

*  The above copyright notice and this permission notice shall be included in

*  all copies or substantial portions of the Software.

*

*  Author:Zheng Fasheng

*

*  Email:zheng_fasheng@outlook.com

*

*  Date:2016/9/4 20:55

*

*  Summary:Declares any class from the boost library



******************************************************************************/

#pragma once

#include <exception>

#include <typeinfo>

#include <type_traits>

#include <typeindex>

#include <string>

namespace detail

template <bool B, class T = void>

struct disable_if_c

typedef T type;

;

template <class T>

struct disable_if_c<true, T> ;

template <class Cond, class T = void>

struct disable_if : public disable_if_c<Cond::value, T> ;

template<bool,class _Ty1,class _Ty2>

struct _If

// type is _Ty2 for assumed false

typedef _Ty2 type;

;

template<class _Ty1,class _Ty2>

struct _If<true, _Ty1, _Ty2>

// type is _Ty1 for assumed true

typedef _Ty1 type;

;

template<class _Ty>

struct add_reference

// add reference

typedef typename std::remove_reference<_Ty>::type& type;

;

template<>

struct add_reference<void>

// add reference

typedef void type;

;

template<>

struct add_reference<const void>

// add reference

typedef const void type;

;

template<>

struct add_reference<volatile void>

// add reference

typedef volatile void type;

;

template<>

struct add_reference<const volatile void>

// add reference

typedef const volatile void type;

;

class bad_cast

public:

explicit bad_cast(const std::string& msg )

_what = msg;



const char* what() const

return _what.data();

;

private:

std::string _what;

;



class Any



public:

Any()

: content(0)





template<typename _Ty>

Any(const _Ty & value)

: content(new holder<typename std::remove_cv< typename std::decay<const _Ty>::type>::type>(value))





Any(const Any & other)

: content(other.content ? other.content->clone() : 0)





//c++11

// Move constructor

Any(Any&& other)

: content(other.content)



other.content = 0;



// Perfect forwarding of ValueType

template<typename _Ty>

Any(_Ty&& value

, typename detail::disable_if< typename std::is_same<Any&, _Ty> >::type* = 0 // disable if value has type `any&`

, typename detail::disable_if< typename std::is_const<_Ty> >::type* = 0) // disable if value has type `const ValueType&&`

: content(new holder< typename std::decay<_Ty>::type >(static_cast<_Ty&&>(value)))





~Any()



if (content)



delete content;



content = nullptr;



public:

Any& swap(Any& rhs)



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

return *this;



Any& operator=(const Any& rhs)



Any(rhs).swap(*this);

return *this;



//c++11

//move assignement

Any& operator=(Any&& rhs)



rhs.swap(*this);

Any().swap(rhs);

return *this;



//perfect forwarding of valueType

template<class valueType>

Any& operator=(valueType&& rhs)



Any(static_cast<valueType&&>(rhs)).swap(*this);

return *this;



public: // queries

bool empty()



return !content;



void clear()



Any().swap(*this);



const std::type_info& type() const



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



private:

class placeholder



public:

virtual ~placeholder()

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

virtual placeholder* clone() const = 0;

;

template<typename _Ty>

class holder : public placeholder



public:

typedef _Ty value_type;

holder(const _Ty& value) :held(value)

holder(_Ty&& value)

:held(static_cast<_Ty&&>(value))





virtual const std::type_info& type() const



return typeid(value_type);



virtual placeholder* clone() const



return new holder(held);



public:

_Ty held;

private:

// intentionally left unimplemented

holder& operator=(const holder &);

;

private: // representation

template<typename _Ty>

friend _Ty * any_cast(Any *);

template<typename _Ty>

friend _Ty * unsafe_any_cast(Any *);

private:

placeholder* content;

;

inline void swap(Any & lhs, Any & rhs)



lhs.swap(rhs);



template<typename _Ty>

_Ty * any_cast(Any * operand)



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

? &static_cast<Any::holder< typename std::remove_cv<_Ty>::type> *>(operand->content)->held

: 0;



template<typename _Ty>

inline const _Ty * any_cast(const Any * operand)



return any_cast<_Ty>(const_cast<Any *>(operand));



template<typename _Ty>

_Ty any_cast(Any & operand)



typedef typename std::remove_reference<_Ty>::type nonref;

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

if (!result)



std::string szReason = "bad any_cast : can't convert ";

szReason += operand.type().name();

szReason += " to ";

szReason += typeid(_Ty).name();

throw detail::bad_cast(szReason);



// Attempt to avoid construction of a temporary object in cases when

// `ValueType` is not a reference. Example:

// `static_cast<std::string>(*result);`

// which is equal to `std::string(*result);`

typedef typename detail::_If<

std::is_reference<_Ty>::value,

_Ty,

typename detail::add_reference<_Ty>::type

>::type ref_type;

return static_cast<ref_type>(*result);



template<typename _Ty>

inline _Ty any_cast(const Any & operand)



typedef typename std::remove_reference<_Ty>::type nonref;

return any_cast<const nonref &>(const_cast<Any &>(operand));



template<typename _Ty>

inline _Ty any_cast(Any&& operand)



static_assert(

std::is_rvalue_reference<_Ty&&>::value /*true if ValueType is rvalue or just a value*/

|| std::is_const< typename std::remove_reference<_Ty>::type >::value,

"any_cast shall not be used for getting nonconst references to temporary objects"

);

return any_cast<_Ty>(operand);

以上是关于C++11实现的Boost库中的Any类的主要内容,如果未能解决你的问题,请参考以下文章

*.pyd 库中的 C++ Boost Python 方法不起作用

哪种算法需要“访问者”(boost 库中的术语)?

模拟实现c++标准库和boost库中的智能指针

boost::any_cast 到我的自定义类

boost库常用库介绍

`boost::any` 和 `std::any` 之间的区别