forked from enlightenment/efl
184 lines
3.8 KiB
C++
184 lines
3.8 KiB
C++
/*
|
|
* Copyright 2019 by its authors. See AUTHORS.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
///
|
|
/// @file eo_wref.hh
|
|
///
|
|
|
|
#ifndef EFL_CXX_WREF_HH
|
|
#define EFL_CXX_WREF_HH
|
|
|
|
#include <eina_optional.hh>
|
|
|
|
#include "eo_ops.hh"
|
|
|
|
namespace efl { namespace eo {
|
|
|
|
/// @addtogroup Efl_Cxx_API
|
|
/// @{
|
|
|
|
/// @brief Weak references to an <em>EO Object</em>.
|
|
///
|
|
template<typename T>
|
|
struct wref
|
|
{
|
|
/// @brief Default constructor.
|
|
///
|
|
/// Create a empty weak reference.
|
|
///
|
|
wref() : _eo_wref(nullptr)
|
|
{
|
|
}
|
|
|
|
/// @brief Empty constructor on nullptr.
|
|
///
|
|
/// Create a empty weak reference.
|
|
///
|
|
wref(std::nullptr_t) : _eo_wref(nullptr)
|
|
{
|
|
}
|
|
|
|
/// @brief Class constructor.
|
|
///
|
|
/// @param obj The <em>EO Object</em> to be referenced.
|
|
///
|
|
/// Create a weak reference to @p obj.
|
|
///
|
|
explicit wref(Eo* obj) : _eo_wref(obj)
|
|
{
|
|
_add();
|
|
}
|
|
|
|
/// @brief Class constructor.
|
|
///
|
|
/// @param obj The <em>EO C++ Object</em> to be referenced.
|
|
///
|
|
/// Create a weak reference to @p obj.
|
|
///
|
|
wref(T obj) : _eo_wref(obj._eo_ptr())
|
|
{
|
|
_add();
|
|
}
|
|
|
|
/// @brief Class destructor.
|
|
///
|
|
~wref()
|
|
{
|
|
if(_eo_wref)
|
|
if(eina::optional<T> p = lock())
|
|
_del();
|
|
}
|
|
|
|
/// @brief Try to acquire a strong reference to the underlying
|
|
/// <em>EO Object</em>.
|
|
///
|
|
/// This function checks whether the weak reference still points to
|
|
/// a valid <em>EO Object</em>. If the reference is still valid it
|
|
/// increments the reference counter of the object and returns a
|
|
/// pointer to it.
|
|
///
|
|
/// @return If the lock was successfully acquired it returns a
|
|
/// strong reference to the <em>EO Object</em>. Otherwise it returns
|
|
/// an empty eina::optional.
|
|
///
|
|
eina::optional<T> lock() const
|
|
{
|
|
if(_eo_wref) // XXX eo_ref() should work on multi-threaded environments
|
|
{
|
|
detail::ref(_eo_wref);
|
|
}
|
|
else
|
|
{
|
|
return nullptr;
|
|
}
|
|
return T(_eo_wref);
|
|
}
|
|
|
|
/// @brief Copy constructor.
|
|
///
|
|
wref(wref const& other)
|
|
: _eo_wref(other._eo_wref)
|
|
{
|
|
if(eina::optional<T> p = lock())
|
|
{
|
|
_add();
|
|
}
|
|
else
|
|
{
|
|
_eo_wref = 0;
|
|
}
|
|
}
|
|
|
|
/// @brief Assignment operator.
|
|
///
|
|
wref& operator=(wref const& other)
|
|
{
|
|
_eo_wref = other._eo_wref;
|
|
if(eina::optional<T> p = lock())
|
|
{
|
|
_add();
|
|
}
|
|
else
|
|
{
|
|
_eo_wref = 0;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
#ifdef EFL_CXXPERIMENTAL
|
|
T operator->() const {
|
|
if (!_eo_wref) return T(nullptr);
|
|
return T(detail::ref(_eo_wref));
|
|
}
|
|
|
|
T operator*() const {
|
|
if (!_eo_wref) return T(nullptr);
|
|
return T(detail::ref(_eo_wref));
|
|
}
|
|
#endif
|
|
|
|
template <typename U>
|
|
bool operator == (U const &other) const
|
|
{
|
|
return other._eo_ptr() == _eo_wref;
|
|
}
|
|
|
|
template <typename U>
|
|
friend bool operator == (U const &other, wref<T> const &thiz)
|
|
{
|
|
return other._eo_ptr() == thiz._eo_wref;
|
|
}
|
|
|
|
private:
|
|
void _add()
|
|
{
|
|
detail::wref_add(_eo_wref, &_eo_wref);
|
|
}
|
|
|
|
void _del()
|
|
{
|
|
detail::wref_del(_eo_wref, &_eo_wref);
|
|
}
|
|
|
|
Eo* _eo_wref; ///< The weak reference.
|
|
};
|
|
|
|
/// @}
|
|
|
|
} } // namespace efl { namespace eo {
|
|
|
|
#endif // EFL_CXX_WREF_HH
|