forked from enlightenment/efl
222 lines
4.6 KiB
C++
222 lines
4.6 KiB
C++
///
|
|
/// @file eo_concrete.hh
|
|
///
|
|
|
|
#ifndef EFL_CXX_EO_CONCRETE_HH
|
|
#define EFL_CXX_EO_CONCRETE_HH
|
|
|
|
#include <cassert>
|
|
#include <stdexcept>
|
|
#include <cstddef>
|
|
#include <eina_optional.hh>
|
|
|
|
#include "eo_ops.hh"
|
|
|
|
#ifndef EFL_CXX_THROW
|
|
#if defined ( EFL_CXX_NO_EXCEPTIONS )
|
|
# define EFL_CXX_THROW(x) std::abort()
|
|
#else
|
|
# define EFL_CXX_THROW(x) throw (x)
|
|
#endif
|
|
#endif
|
|
|
|
#if !defined(EFL_DOXYGEN) && !defined(EO_CXX_INHERIT)
|
|
# define EO_CXX_INHERIT(name) ::eo_cxx name
|
|
#elif !defined(EO_CXX_INHERIT)
|
|
# define EO_CXX_INHERIT(name) name
|
|
#endif
|
|
|
|
namespace efl { namespace eo {
|
|
|
|
/// @addtogroup Efl_Cxx_API
|
|
/// @{
|
|
|
|
/// @brief Creates concrete versions for <em>Eo</em> wrappers.
|
|
///
|
|
/// This class creates the concrete version of all C++ <em>Eo</em> wrappers.
|
|
/// It holds the Eo pointer that is used on all operations and provides some
|
|
/// functions for manipulating it.
|
|
///
|
|
struct concrete
|
|
{
|
|
/// @brief Class constructor.
|
|
///
|
|
/// @param eo The <em>EO Object</em>.
|
|
///
|
|
/// efl::eo::concrete constructors semantics are that of stealing the
|
|
/// <em>EO Object</em> lifecycle management. Its constructors do not
|
|
/// increment the <em>EO</em> reference counter but the destructors
|
|
/// do decrement.
|
|
///
|
|
explicit concrete(Eo* eo) : _eo_raw(eo)
|
|
{
|
|
}
|
|
|
|
|
|
/// @brief Default constructor.
|
|
///
|
|
/// Constructs a NULL initialized efl::eo::concrete object.
|
|
///
|
|
concrete() : _eo_raw(nullptr)
|
|
{
|
|
}
|
|
|
|
/// @brief Class destructor.
|
|
///
|
|
~concrete()
|
|
{
|
|
if(_eo_raw)
|
|
detail::unref(_eo_raw);
|
|
}
|
|
|
|
concrete(concrete const& other)
|
|
{
|
|
if(other._eo_raw)
|
|
_eo_raw = detail::ref(other._eo_raw);
|
|
}
|
|
|
|
concrete(concrete&& other)
|
|
{
|
|
if(_eo_raw) detail::unref(_eo_raw);
|
|
_eo_raw = other._eo_raw;
|
|
other._eo_raw = nullptr;
|
|
}
|
|
|
|
/// @brief Assignment operator.
|
|
///
|
|
concrete& operator=(concrete const& other)
|
|
{
|
|
if(_eo_raw)
|
|
{
|
|
detail::unref(_eo_raw);
|
|
_eo_raw = nullptr;
|
|
}
|
|
if(other._eo_raw)
|
|
_eo_raw = detail::ref(other._eo_raw);
|
|
return *this;
|
|
}
|
|
|
|
concrete& operator=(concrete&& other)
|
|
{
|
|
if(_eo_raw)
|
|
{
|
|
detail::unref(_eo_raw);
|
|
_eo_raw = nullptr;
|
|
}
|
|
std::swap(_eo_raw, other._eo_raw);
|
|
return *this;
|
|
}
|
|
|
|
/// @brief Return a pointer to the <em>EO Object</em> stored in this
|
|
/// instance.
|
|
///
|
|
/// @return A pointer to the opaque <em>EO Object</em>.
|
|
///
|
|
Eo* _eo_ptr() const { return _eo_raw; }
|
|
|
|
/// @brief Releases the reference from this concrete object and
|
|
/// return the pointer to the <em>EO Object</em> stored in this
|
|
/// instance.
|
|
///
|
|
/// @return A pointer to the opaque <em>EO Object</em>.
|
|
///
|
|
Eo* _release()
|
|
{
|
|
Eo* tmp = _eo_raw;
|
|
_eo_raw = nullptr;
|
|
return tmp;
|
|
}
|
|
|
|
/// @brief Reset the current pointer to reference a new Eo object.
|
|
///
|
|
void _reset(Eo* _ptr = nullptr)
|
|
{
|
|
if(_eo_raw)
|
|
detail::unref(_eo_raw);
|
|
_eo_raw = _ptr;
|
|
}
|
|
|
|
explicit operator bool() const
|
|
{
|
|
return _eo_raw;
|
|
}
|
|
protected:
|
|
Eo* _eo_raw; ///< The opaque <em>EO Object</em>.
|
|
};
|
|
|
|
template<class CharT, class Traits>
|
|
inline std::basic_ostream<CharT, Traits>&
|
|
operator<<(std::basic_ostream<CharT, Traits>& os, concrete const& eo)
|
|
{
|
|
return os << eo._eo_ptr();
|
|
}
|
|
|
|
inline bool operator==(concrete const& lhs, concrete const& rhs)
|
|
{
|
|
return lhs._eo_ptr() == rhs._eo_ptr();
|
|
}
|
|
|
|
inline bool operator!=(concrete const& lhs, concrete const& rhs)
|
|
{
|
|
return !(lhs == rhs);
|
|
}
|
|
|
|
namespace detail {
|
|
|
|
template <typename T>
|
|
struct extension_inheritance;
|
|
|
|
template<>
|
|
struct extension_inheritance<concrete>
|
|
{
|
|
template <typename T>
|
|
struct type
|
|
{
|
|
operator concrete() const
|
|
{
|
|
return concrete(eo_ref(static_cast<T const*>(this)->_eo_ptr()));
|
|
}
|
|
|
|
};
|
|
};
|
|
|
|
}
|
|
|
|
/// @brief Downcast @p U to @p T.
|
|
///
|
|
/// @param T An <em>EO C++ Class</em>.
|
|
/// @param U An <em>EO C++ Class</em>.
|
|
///
|
|
/// @param object The target object.
|
|
/// @return This function returns a new instance of @p T if the
|
|
/// downcast is successful --- otherwise it raises a @c
|
|
/// std::runtime_error.
|
|
///
|
|
template <typename T, typename U>
|
|
T downcast(U object)
|
|
{
|
|
Eo *eo = object._eo_ptr();
|
|
|
|
if(detail::isa(eo, T::_eo_class()))
|
|
{
|
|
return T(detail::ref(eo));
|
|
}
|
|
else
|
|
{
|
|
EFL_CXX_THROW(std::runtime_error("Invalid cast"));
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
struct is_eolian_object : std::false_type {};
|
|
template <typename T>
|
|
struct is_eolian_object<T const> : is_eolian_object<T> {};
|
|
template <>
|
|
struct is_eolian_object<eo::concrete> : std::true_type {};
|
|
|
|
/// @}
|
|
|
|
} } // namespace efl { namespace eo {
|
|
|
|
#endif // EFL_CXX_EO_CONCRETE_HH
|