/* * 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 #include "eo_ops.hh" namespace efl { namespace eo { /// @addtogroup Efl_Cxx_API /// @{ /// @brief Weak references to an EO Object. /// template 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 EO Object to be referenced. /// /// Create a weak reference to @p obj. /// explicit wref(Eo* obj) : _eo_wref(obj) { _add(); } /// @brief Class constructor. /// /// @param obj The EO C++ Object 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 p = lock()) _del(); } /// @brief Try to acquire a strong reference to the underlying /// EO Object. /// /// This function checks whether the weak reference still points to /// a valid EO Object. 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 EO Object. Otherwise it returns /// an empty eina::optional. /// eina::optional 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 p = lock()) { _add(); } else { _eo_wref = 0; } } /// @brief Assignment operator. /// wref& operator=(wref const& other) { _eo_wref = other._eo_wref; if(eina::optional 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 bool operator == (U const &other) const { return other._eo_ptr() == _eo_wref; } template friend bool operator == (U const &other, wref 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