You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

462 lines
15 KiB

/*
* 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.
*/
#ifndef EINA_RANGE_TYPES_HH_
#define EINA_RANGE_TYPES_HH_
/**
* @addtogroup Eina_Cxx_Content_Access_Group
*
* @{
*/
namespace efl { namespace eina {
/**
* @defgroup Eina_Cxx_Range_Group Range
* @ingroup Eina_Cxx_Content_Access_Group
*
* @{
*/
/**
* @brief Range implementation for immutable collections.
*/
template <typename T, typename Traits>
struct _const_range_template
{
typedef typename container_value_type<T>::type
value_type; /**< The type of each element. */
typedef typename Traits::template const_iterator<value_type>::type const_iterator; /**< Type for constant iterator to the range. */
typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for iterator to the range. */
typedef value_type& reference; /**< Type for a reference to an element. */
typedef value_type const& const_reference; /**< Type for a constant reference to an element. */
typedef T* pointer; /**< Type for a pointer to an element. */
typedef T const* const_pointer; /**< Type for a constant pointer to an element. */
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for reverse iterator to the range. */
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; /**< Type for constant reverse iterator to the range. */
typedef std::size_t size_type; /**< Type for size information. */
typedef std::ptrdiff_t difference_type; /**< Type to represent the distance between two iterators. */
typedef typename Traits::template const_native_handle<T>::type native_handle_type; /**< Type for the native handle of the container. */
typedef _const_range_template<T, Traits> _self_type; /**< Type of the range itself. */
/**
* @brief Creates a singular range object
*/
_const_range_template()
{}
/**
* @brief Creates a range object wrapping the given native container handle.
*/
_const_range_template(native_handle_type handle)
: _handle(handle) {}
/**
* @brief Release the handle of the native Eina container.
* @return Handle for the native Eina container.
*/
native_handle_type release_native_handle()
{
auto h = _handle;
_handle = nullptr;
return h;
}
/**
* @brief Get a constant handle for the native Eina container.
* @return Constant handle for the native Eina container.
*/
native_handle_type native_handle() const { return _handle; }
/**
* @brief Get a constant reference to the last element.
* @return Constant reference to the last element of the range.
*/
value_type const& back() const
{
return Traits::template back<value_type>(_handle);
}
/**
* @brief Get a constant reference to the first element.
* @return Constant reference to the first element of the range.
*/
value_type const& front() const
{
return Traits::template front<value_type>(_handle);
}
/**
* @brief Get a constant iterator pointing to the first element of the range.
* @return Constant iterator to the initial position of the range.
*
* This member function returns a constant iterator pointing to the
* first element of the range. If the range contains no elements the
* returned iterator is the same as the one returned by @ref end() const.
*/
const_iterator begin() const
{
return cbegin();
}
/**
* @brief Get a constant iterator to the position following the last element of the range.
* @return Constant iterator to the final position of the range.
*
* This member function returns a constant iterator to the position
* following the last element in the range. If the range contains no
* elements the returned iterator is the same as the one returned by
* @ref begin() const.
*
* @note Note that attempting to access this position causes undefined
* behavior.
*/
const_iterator end() const
{
return cend();
}
/**
* @brief Get a constant reverse iterator pointing to the reverse begin of the range.
* @return Constant reverse iterator pointing to the reverse begin of the range.
*
* This member function works like @ref rbegin() const but is granted
* to return a constant reverse iterator even for a range to a mutable
* collection.
*/
const_reverse_iterator crbegin() const
{
return const_reverse_iterator(Traits::template rbegin<value_type>(_handle));
}
/**
* @brief Get a constant reverse iterator pointing to the reverse end of the range.
* @return Constant reverse iterator pointing to the reverse end of the range.
*
* This member function works like @ref rend() const but is granted to
* return a constant reverse iterator even for range to a mutable
* collection.
*/
const_reverse_iterator crend() const
{
return const_reverse_iterator(Traits::template rend<value_type>(_handle));
}
/**
* @brief Get a constant iterator pointing to the first element of the range.
* @return Constant iterator to the initial position of the range.
*
* This member function works like @ref begin() const but is granted
* to return a constant iterator even for a range to a mutable
* collection.
*/
const_iterator cbegin() const
{
return Traits::template cbegin<value_type>(_handle);
}
/**
* @brief Get a constant iterator to the position following the last element of the range.
* @return Constant iterator to the final position of the range.
*
* This member function works like @ref end() const but is granted to
* return a constant iterator even for a range to a mutable collection.
*/
const_iterator cend() const
{
return Traits::template cend<value_type>(_handle);
}
/**
* @brief Get a constant reverse iterator pointing to the reverse begin of the range.
* @return Constant reverse iterator pointing to the reverse begin of the range.
*
* This member function returns a constant reverse iterator pointing
* to the last element of the range. If the range is empty the
* returned reverse iterator is the same as the one returned by
* @ref rend().
*/
const_reverse_iterator rbegin()
{
return crbegin();
}
/**
* @brief Get a constant reverse iterator pointing to the reverse end of the range.
* @return Constant reverse iterator pointing to the reverse end of the range.
*
* This member function returns a constant reverse iterator pointing
* to the position before the first element of the range. If the range
* is empty the returned iterator is the same as the one returned by
* @ref rbegin().
*
* @note Note that attempting to access this position causes undefined
* behavior.
*/
const_reverse_iterator rend()
{
return crend();
}
/**
* @brief Check if the range does not contain any elements.
* @return @c true if there is no elements in the range, @c false otherwise.
*
* This member function returns @c true if the range does not contain
* any elements, otherwise it returns @c false.
*/
bool empty() const
{
return Traits::template empty<value_type>(_handle);
}
/**
* @brief Get the number of elements in the range.
* @return Number of elements in the range.
*
* This member function returns the current number of elements in the
* range.
*/
size_type size() const
{
return Traits::template size<value_type>(_handle);
}
/**
* @brief Swap content with another range of the same type.
* @param other Another range of the same type.
*/
void swap(_self_type& other)
{
std::swap(_handle, other._handle);
}
protected:
/**
* @internal
*/
native_handle_type _handle;
};
/**
* @brief Swap content between two @ref _const_range_template.
* @param lhs First @c _const_range_template object.
* @param rhs Second @c _const_range_template object.
*/
template <typename T, typename Traits>
void swap(_const_range_template<T, Traits>& lhs, _const_range_template<T, Traits>& rhs)
{
lhs.swap(rhs);
}
/**
* @brief Range implementation for mutable collections.
*/
template <typename T, typename Traits>
struct _mutable_range_template : _const_range_template<T, Traits>
{
typedef typename container_value_type<T>::type
value_type; /**< The type of each element. */
typedef value_type& reference_type;
typedef value_type const& const_reference_type;
typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for a iterator to the range. */
typedef std::reverse_iterator<iterator> reverse_iterator; /**< Type for constant reverse iterator to the range. */
typedef typename Traits::template native_handle<value_type>::type native_handle_type; /**< Type for the native handle of the container. */
typedef _const_range_template<T, Traits> _base_type; /**< Type for the base class. */
/**
* @brief Creates a range object wrapping the given native container handle.
*/
_mutable_range_template(native_handle_type handle)
: _base_type(handle) {}
/**
* @brief Release the handle of the native Eina container.
* @return Handle for the native Eina container.
*/
native_handle_type release_native_handle()
{
auto h = _handle;
_handle = nullptr;
return const_cast<native_handle_type>(h);
}
/**
* @brief Get a constant handle for the native Eina container.
* @return Constant handle for the native Eina container.
*/
native_handle_type native_handle() const
{
return Traits::template native_handle_from_const<T>(_base_type::native_handle());
}
/**
* @brief Get a reference to the last element.
* @return Reference to the last element of the range.
*/
reference_type back() const
{
return Traits::template back<value_type>(native_handle());
}
/**
* @brief Get a reference to the first element.
* @return Reference to the first element of the range.
*/
reference_type front() const
{
return Traits::template front<value_type>(native_handle());
}
/**
* @brief Get an iterator pointing to the first element of the range.
* @return Iterator to the initial position of the range.
*
* This member function returns an iterator pointing to the first
* element of the range. If the range contains no elements the
* returned iterator is the same as the one returned by @ref end() const.
*/
iterator begin() const
{
return Traits::template begin<value_type>(native_handle());
}
/**
* @brief Get an iterator to the position following the last element of the range.
* @return Iterator to the final position of the range.
*
* This member function returns an iterator to the position following
* the last element in the range. If the range contains no elements
* the returned iterator is the same as the one returned by
* @ref begin() const.
*
* @note Note that attempting to access this position causes undefined
* behavior.
*/
iterator end() const
{
return Traits::template end<value_type>(native_handle());
}
/**
* @brief Get a reverse iterator pointing to the reverse begin of the range.
* @return Reverse iterator pointing to the reverse begin of the range.
*
* This member function returns a reverse iterator pointing to the
* last element of the range. If the range is empty the returned
* reverse iterator is the same as the one returned by @ref rend().
*/
reverse_iterator rbegin() const
{
return Traits::template rbegin<value_type>(native_handle());
}
/**
* @brief Get a reverse iterator pointing to the reverse end of the range.
* @return Reverse iterator pointing to the reverse end of the range.
*
* This member function returns a reverse iterator pointing to the
* position before the first element of the range. If the range is
* empty the returned iterator is the same as the one returned by
* @ref rbegin().
*
* @note Note that attempting to access this position causes undefined
* behavior.
*/
reverse_iterator rend() const
{
return Traits::template rend<value_type>(native_handle());
}
protected:
/**
* @internal
*/
using _base_type::_handle;
};
/**
* Range class.
*
* Provide objects for accessing and/or modifying elements inside a
* container without modifying the container itself.
*/
template <typename T, typename Traits>
struct _range_template : private std::conditional
<std::is_const<T>::value
, _const_range_template<typename nonconst_container_value_type<T>::type, Traits>
, _mutable_range_template<typename nonconst_container_value_type<T>::type, Traits>
>::type
{
typedef std::integral_constant<bool, !std::is_const<T>::value> is_mutable; /**< Type that specifies if the elements can be modified. */
typedef typename nonconst_container_value_type<T>::type value_type; /**< The type of each element. */
typedef typename std::conditional<is_mutable::value, _mutable_range_template<value_type, Traits>
, _const_range_template<value_type, Traits> >::type _base_type; /**< Type for the base class. */
typedef typename _base_type::native_handle_type native_handle_type; /**< Type for the native handle of the container. */
typedef value_type& reference; /**< Type for a reference to an element. */
typedef value_type const& const_reference; /**< Type for a constant reference to an element. */
typedef value_type* pointer; /**< Type for a pointer to an element. */
typedef value_type const* const_pointer; /**< Type for a constant pointer to an element. */
typedef typename Traits::template const_iterator<value_type>::type const_iterator; /**< Type for constant iterator to the range. */
typedef typename _base_type::const_reverse_iterator const_reverse_iterator; /**< Type for constant reverse iterator to the range. */
typedef typename Traits::template iterator<value_type>::type iterator; /**< Type for iterator to the range. */
typedef typename _base_type::reverse_iterator reverse_iterator; /**< Type for reverse iterator to the range. */
typedef typename _base_type::size_type size_type; /**< Type for size information. */
typedef typename _base_type::difference_type difference_type; /**< Type to represent the distance between two iterators. */
/**
* @brief Creates a singular range object
*/
_range_template()
{}
/**
* @brief Creates a range object wrapping the given native container handle.
*/
_range_template(native_handle_type handle)
: _base_type(handle)
{}
using _base_type::release_native_handle;
using _base_type::native_handle;
using _base_type::back;
using _base_type::front;
using _base_type::begin;
using _base_type::end;
using _base_type::rbegin;
using _base_type::rend;
using _base_type::cbegin;
using _base_type::cend;
using _base_type::crbegin;
using _base_type::crend;
using _base_type::empty;
using _base_type::size;
using _base_type::swap;
protected:
using _base_type::_handle;
};
/**
* @}
*/
} }
/**
* @}
*/
#endif