mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
191 lines
4.3 KiB
C++
191 lines
4.3 KiB
C++
/*
|
|
* Boost Software License - Version 1.0 - August 17th, 2003
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person or organization
|
|
* obtaining a copy of the software and accompanying documentation covered by
|
|
* this license (the "Software") to use, reproduce, display, distribute,
|
|
* execute, and transmit the Software, and to prepare derivative works of the
|
|
* Software, and to permit third-parties to whom the Software is furnished to
|
|
* do so, all subject to the following:
|
|
*
|
|
* The copyright notices in the Software and this entire statement, including
|
|
* the above license grant, this restriction and the following disclaimer,
|
|
* must be included in all copies of the Software, in whole or in part, and
|
|
* all derivative works of the Software, unless such copies or derivative
|
|
* works are solely in the form of machine-executable object code generated by
|
|
* a source language processor.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
// EQEmu::Any is a modified version of Boost::Any and as such retains the Boost licensing.
|
|
|
|
#ifndef EQEMU_COMMON_ANY_H
|
|
#define EQEMU_COMMON_ANY_H
|
|
|
|
#include <algorithm>
|
|
#include <typeinfo>
|
|
|
|
namespace EQEmu
|
|
{
|
|
class Any
|
|
{
|
|
public:
|
|
Any()
|
|
: content(nullptr)
|
|
{
|
|
}
|
|
|
|
template<typename ValueType>
|
|
Any(const ValueType &value)
|
|
: content(new Holder<ValueType>(value))
|
|
{
|
|
}
|
|
|
|
Any(const Any &other)
|
|
: content(other.content ? other.content->clone() : 0)
|
|
{
|
|
}
|
|
|
|
~Any()
|
|
{
|
|
if(content)
|
|
delete content;
|
|
}
|
|
|
|
Any& swap(Any &rhs)
|
|
{
|
|
std::swap(content, rhs.content);
|
|
return *this;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
Any& operator=(const ValueType &rhs)
|
|
{
|
|
Any(rhs).swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
Any& operator=(Any rhs)
|
|
{
|
|
rhs.swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
bool empty() const
|
|
{
|
|
return !content;
|
|
}
|
|
|
|
const std::type_info& type() const
|
|
{
|
|
return content ? content->type() : typeid(void);
|
|
}
|
|
|
|
class Placeholder
|
|
{
|
|
public:
|
|
virtual ~Placeholder()
|
|
{
|
|
}
|
|
|
|
virtual const std::type_info& type() const = 0;
|
|
virtual Placeholder* clone() const = 0;
|
|
};
|
|
|
|
|
|
template<typename ValueType>
|
|
class Holder : public Placeholder
|
|
{
|
|
public:
|
|
Holder(const ValueType &value)
|
|
: held(value)
|
|
{
|
|
}
|
|
|
|
virtual const std::type_info& type() const
|
|
{
|
|
return typeid(ValueType);
|
|
}
|
|
|
|
virtual Placeholder* clone() const
|
|
{
|
|
return new Holder(held);
|
|
}
|
|
|
|
ValueType held;
|
|
|
|
private:
|
|
Holder& operator=(const Holder&);
|
|
};
|
|
|
|
private:
|
|
template<typename ValueType>
|
|
friend ValueType* any_cast(Any*);
|
|
|
|
template<typename ValueType>
|
|
friend ValueType* unsafe_any_cast(Any*);
|
|
|
|
Placeholder* content;
|
|
};
|
|
|
|
class bad_any_cast : public std::bad_cast
|
|
{
|
|
public:
|
|
virtual const char * what() const throw()
|
|
{
|
|
return "DBI::bad_any_cast: failed conversion using DBI::any_cast";
|
|
}
|
|
};
|
|
|
|
template<typename ValueType>
|
|
ValueType* any_cast(Any* operand)
|
|
{
|
|
return operand &&
|
|
operand->type() == typeid(ValueType) ? &static_cast<Any::Holder<ValueType>*>(operand->content)->held : nullptr;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
inline const ValueType* any_cast(const Any* operand)
|
|
{
|
|
return any_cast<ValueType>(const_cast<Any*>(operand));
|
|
}
|
|
|
|
template<typename ValueType>
|
|
ValueType any_cast(Any& operand)
|
|
{
|
|
typedef typename std::remove_reference<ValueType>::type nonref;
|
|
nonref* result = any_cast<nonref>(&operand);
|
|
if(!result)
|
|
throw bad_any_cast();
|
|
return *result;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
inline ValueType any_cast(const Any& operand)
|
|
{
|
|
typedef typename std::remove_reference<ValueType>::type nonref;
|
|
return any_cast<const nonref&>(const_cast<Any&>(operand));
|
|
}
|
|
|
|
template<typename ValueType>
|
|
inline ValueType* unsafe_any_cast(Any* operand)
|
|
{
|
|
return &static_cast<Any::Holder<ValueType>*>(operand->content)->held;
|
|
}
|
|
|
|
template<typename ValueType>
|
|
inline const ValueType* unsafe_any_cast(const Any* operand)
|
|
{
|
|
return unsafe_any_cast<ValueType>(const_cast<Any*>(operand));
|
|
}
|
|
}
|
|
|
|
#endif
|