|
Shinya Kitaoka |
810553 |
#pragma once
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef TCG_BASE_H
|
|
Toshihiro Shimizu |
890ddd |
#define TCG_BASE_H
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
namespace tcg
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
\file tcg_base.h
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
\brief This file contains the implementation of some handy base classes
|
|
Toshihiro Shimizu |
890ddd |
that can be inherited from.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
\brief The empty_type can be used as default template parameter in cases
|
|
Toshihiro Shimizu |
890ddd |
where the template parameter may be omitted.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
struct empty_type {
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
\brief The noncopyable class can be inherited to forbid access to the
|
|
Toshihiro Shimizu |
890ddd |
copy constructor and assignment operator.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
\note A template parameter is provided to permit the empty base
|
|
Toshihiro Shimizu |
890ddd |
class optimization. In case this optimization is not needed,
|
|
Toshihiro Shimizu |
890ddd |
please use boost::noncopyable instead.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename b="empty_type"></typename>
|
|
Toshihiro Shimizu |
890ddd |
struct noncopyable : public B {
|
|
Toshihiro Shimizu |
890ddd |
noncopyable() {}
|
|
Toshihiro Shimizu |
890ddd |
//noncopyable(const B& b) : B(b) {} // Would introduce additional copies
|
|
Toshihiro Shimizu |
890ddd |
// along the inheritance chain. Not worth it.
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Toshihiro Shimizu |
890ddd |
~noncopyable() {} //!< Protected destructor since the class
|
|
Toshihiro Shimizu |
890ddd |
//! is intended for nonvirtual inheritance.
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Toshihiro Shimizu |
890ddd |
noncopyable(const noncopyable &); //!< Non-accessible copy constructor.
|
|
Toshihiro Shimizu |
890ddd |
noncopyable &operator=(const noncopyable &); //!< Non-accessible assignment operator.
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
\brief The polymorphic class just implements an empty class
|
|
Toshihiro Shimizu |
890ddd |
with a virtual destructor.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
\details It can be useful in certain occasions:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
\li Explicitly marks derived classes as polymporphic, and
|
|
Toshihiro Shimizu |
890ddd |
spares the need to write a virtual destructor.
|
|
Toshihiro Shimizu |
890ddd |
\li It's noncopyable, disabling value semantics.
|
|
Toshihiro Shimizu |
890ddd |
\li Provides a common base class to polymorphic hierarchies.
|
|
Toshihiro Shimizu |
890ddd |
\li Enables lightweight type erasure without resorting to
|
|
Toshihiro Shimizu |
890ddd |
a wrapper class like boost::any, assuming you have
|
|
Toshihiro Shimizu |
890ddd |
enough control of the involved class to add a base class.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class polymorphic : noncopyable<> // Noncopyable to prevent slicing
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Toshihiro Shimizu |
890ddd |
polymorphic() {} //!< Protected constructor to ensure that the
|
|
Toshihiro Shimizu |
890ddd |
//! class is only used as base class.
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
virtual ~polymorphic() {} //!< A virtual destructor as every good base
|
|
Toshihiro Shimizu |
890ddd |
//! class must have.
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
The tcg::safe_bool template class is a simple implementation
|
|
Toshihiro Shimizu |
890ddd |
of the classic Safe Bool Idiom, meant to be used inside tcg.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
For a better implementation, you should consider looking into
|
|
Toshihiro Shimizu |
890ddd |
Boost.Spirit.Safe_Bool.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename b="empty_type" t,="" typename=""> // B is used for base class chaining, to deal with</typename>
|
|
Toshihiro Shimizu |
890ddd |
class safe_bool : public B // the empty class optimization
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
class dummy
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
struct detail {
|
|
Toshihiro Shimizu |
890ddd |
dummy *member;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
typedef dummy *detail::*bool_type;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
safe_bool() {}
|
|
Toshihiro Shimizu |
890ddd |
//safe_bool(const B& b) : B(b) {} // Would introduce additional copies
|
|
Toshihiro Shimizu |
890ddd |
// along the inheritance chain. Not worth it.
|
|
Toshihiro Shimizu |
890ddd |
operator bool_type() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return static_cast<const *="" t="">(this)->operator_bool() ? &detail::member : 0;</const>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Toshihiro Shimizu |
890ddd |
~safe_bool() {} //!< Protected destructor since the class
|
|
Toshihiro Shimizu |
890ddd |
//! is intended for nonvirtual inheritance.
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Toshihiro Shimizu |
890ddd |
bool operator==(const safe_bool &);
|
|
Toshihiro Shimizu |
890ddd |
bool operator!=(const safe_bool &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} // namespace tcg
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif // TCG_BASE_H
|