diff options
Diffstat (limited to 'src/bindings/eo_cxx/eo_concrete.hh')
-rw-r--r-- | src/bindings/eo_cxx/eo_concrete.hh | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/src/bindings/eo_cxx/eo_concrete.hh b/src/bindings/eo_cxx/eo_concrete.hh new file mode 100644 index 0000000000..4d379a618b --- /dev/null +++ b/src/bindings/eo_cxx/eo_concrete.hh @@ -0,0 +1,271 @@ +/// +/// @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" +#include "eo_event.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 + +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 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; + } + + /// @brief Get the reference count of this object. + /// + /// @return The referencer count of this object. + /// + int ref_get() const { return detail::ref_get(_eo_raw); } + + /// @brief Set the parent of this object. + /// + /// @param parent The new parent. + /// + void parent_set(concrete parent) + { + detail::parent_set(_eo_raw, parent._eo_ptr()); + } + + /// @brief Get the parent of this object. + /// + /// @return An @ref efl::eo::concrete instance that binds the parent + /// object. Returns NULL if there is no parent. + /// + eina::optional<concrete> parent_get() + { + Eo *r = detail::parent_get(_eo_raw); + if(!r) return nullptr; + else + { + detail::ref(r); // XXX eo_parent_get does not call eo_ref so we may. + return concrete(r); + } + } + + /// @brief Get debug information of this object. + /// + /// @return The root node of the debug information tree. + /// + Eo_Dbg_Info dbg_info_get() + { + Eo_Dbg_Info info; + detail::dbg_info_get(_eo_raw, &info); + return info; + } + + explicit operator bool() const + { + return _eo_raw; + } + protected: + Eo* _eo_raw; ///< The opaque <em>EO Object</em>. +}; + +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")); + } +} + +/// +/// @brief Type used to hold the parent passed to concrete Eo C++ +/// constructors. +/// +struct parent_type +{ + Eo* _eo_raw; +}; + +/// +/// @brief The expression type declaring the assignment operator used +/// in the parent argument of the concrete Eo C++ class. +/// +struct parent_expr +{ + parent_type operator=(efl::eo::concrete const& parent) const + { + return { parent._eo_ptr() }; + } + + template <typename T> + parent_type operator=(T const& parent) const + { + return { parent._eo_ptr() }; + } + parent_type operator=(std::nullptr_t) const + { + return { nullptr }; + } +}; + +/// +/// @brief Placeholder for the parent argument. +/// +parent_expr const parent = {}; + +/// @} + +} } // namespace efl { namespace eo { + +#endif // EFL_CXX_EO_CONCRETE_HH |