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

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

*

*  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:[email protected]

*

*  Date:2016/9/4 20:55

*

*  Summary:Declares any class from the boost library

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

#pragma once

#include

#include

#include

#include

#include

namespace detail{

template

struct disable_if_c {

typedef T type;

};

template

struct disable_if_c {};

template

struct disable_if : public disable_if_c {};

template

struct _If

{ // type is _Ty2 for assumed false

typedef _Ty2 type;

};

template

struct _If

{ // type is _Ty1 for assumed true

typedef _Ty1 type;

};

template

struct add_reference

{ // add reference

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

};

template<>

struct add_reference

{ // add reference

typedef void type;

};

template<>

struct add_reference

{ // add reference

typedef const void type;

};

template<>

struct add_reference

{ // add reference

typedef volatile void type;

};

template<>

struct add_reference

{ // 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

Any(const _Ty & value)

: content(new holder::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

Any(_Ty&& value

, typename detail::disable_if< typename std::is_same >::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

Any& operator=(valueType&& rhs)

{

Any(static_cast(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

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

friend _Ty * any_cast(Any *);

template

friend _Ty * unsafe_any_cast(Any *);

private:

placeholder* content;

};

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

{

lhs.swap(rhs);

}

template

_Ty * any_cast(Any * operand)

{

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

? &static_cast::type> *>(operand->content)->held

: 0;

}

template

inline const _Ty * any_cast(const Any * operand)

{

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

}

template

_Ty any_cast(Any & operand)

{

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

nonref * result = any_cast(&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(*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(*result);

}

template

inline _Ty any_cast(const Any & operand)

{

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

return any_cast(const_cast(operand));

}

template

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类)