...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
boost::stl_interfaces::v1::sequence_container_interface
// In header: <boost/stl_interfaces/sequence_container_interface.hpp> template<typename Derived, element_layout Contiguity> struct sequence_container_interface { // construct/copy/destruct template<typename D = Derived> constexpr auto operator=(std::initializer_list< typename D::value_type >) noexcept(noexcept(std::declval< D & >().assign(il.begin(), il.end())))); // public member functions template<typename D = Derived> constexpr auto empty() noexcept(noexcept(std::declval< D & >().begin()==std::declval< D & >().end()))); template<typename D = Derived> constexpr auto empty() const noexcept(noexcept(std::declval< D const & >().begin()==std::declval< D const & >().end()))); template<typename D = Derived, element_layout C = Contiguity, typename Enable = std::enable_if_t<C == element_layout::contiguous> > constexpr auto data() noexcept(noexcept(std::declval< D & >().begin()))); template<typename D = Derived, element_layout C = Contiguity, typename Enable = std::enable_if_t<C == element_layout::contiguous> > constexpr auto data() const noexcept(noexcept(std::declval< D const & >().begin()))); template<typename D = Derived> constexpr auto size() noexcept(noexcept(std::declval< D & >().end() - std::declval< D & >().begin()))); template<typename D = Derived> constexpr auto size() const noexcept(noexcept(std::declval< D const & >().end() - std::declval< D const & >().begin()))); template<typename D = Derived> constexpr auto front() noexcept(noexcept(*std::declval< D & >().begin()))); template<typename D = Derived> constexpr auto front() const noexcept(noexcept(*std::declval< D const & >().begin()))); template<typename D = Derived> constexpr auto push_front(typename D::value_type const &) noexcept(noexcept(std::declval< D & >().emplace_front(x)))); template<typename D = Derived> constexpr auto push_front(typename D::value_type &&) noexcept(noexcept(std::declval< D & >().emplace_front(std::move(x))))); template<typename D = Derived> constexpr auto pop_front() noexcept; template<typename D = Derived, typename Enable = std::enable_if_t< v1_dtl::decrementable_sentinel<D>::value && v1_dtl::common_range<D>::value> > constexpr auto back() noexcept(noexcept(*std::prev(std::declval< D & >().end())))); template<typename D = Derived, typename Enable = std::enable_if_t< v1_dtl::decrementable_sentinel<D>::value && v1_dtl::common_range<D>::value> > constexpr auto back() const noexcept(noexcept(*std::prev(std::declval< D const & >().end())))); template<typename D = Derived> constexpr auto push_back(typename D::value_type const &) noexcept(noexcept(std::declval< D & >().emplace_back(x)))); template<typename D = Derived> constexpr auto push_back(typename D::value_type &&) noexcept(noexcept(std::declval< D & >().emplace_back(std::move(x))))); template<typename D = Derived> constexpr auto pop_back() noexcept; template<typename D = Derived> constexpr auto operator[](typename D::size_type) noexcept(noexcept(std::declval< D & >().begin()[n]))); template<typename D = Derived> constexpr auto operator[](typename D::size_type) const noexcept(noexcept(std::declval< D const & >().begin()[n]))); template<typename D = Derived> constexpr auto at(typename D::size_type); template<typename D = Derived> constexpr auto at(typename D::size_type) const; template<typename D = Derived, typename Iter = typename D::const_iterator> constexpr Iter begin() const noexcept(noexcept(std::declval< D & >().begin()))); template<typename D = Derived, typename Iter = typename D::const_iterator> constexpr Iter end() const noexcept(noexcept(std::declval< D & >().end()))); template<typename D = Derived> constexpr auto cbegin() const noexcept(noexcept(std::declval< D const & >().begin()))); template<typename D = Derived> constexpr auto cend() const noexcept(noexcept(std::declval< D const & >().end()))); template<typename D = Derived, typename Enable = std::enable_if_t<v1_dtl::common_range<D>::value> > constexpr auto rbegin() noexcept(noexcept(stl_interfaces::make_reverse_iterator(std::declval< D & >().end())))); template<typename D = Derived, typename Enable = std::enable_if_t<v1_dtl::common_range<D>::value> > constexpr auto rend() noexcept(noexcept(stl_interfaces::make_reverse_iterator(std::declval< D & >().begin())))); template<typename D = Derived> constexpr auto rbegin() const noexcept(noexcept(std::declval< D & >().rbegin()))); template<typename D = Derived> constexpr auto rend() const noexcept(noexcept(std::declval< D & >().rend()))); template<typename D = Derived> constexpr auto crbegin() const noexcept(noexcept(std::declval< D const & >().rbegin()))); template<typename D = Derived> constexpr auto crend() const noexcept(noexcept(std::declval< D const & >().rend()))); template<typename D = Derived> constexpr auto insert(typename D::const_iterator, typename D::value_type const &) noexcept(noexcept(std::declval< D & >().emplace(pos, x)))); template<typename D = Derived> constexpr auto insert(typename D::const_iterator, typename D::value_type &&) noexcept(noexcept(std::declval< D & >() .emplace(pos, std::move(x))))); template<typename D = Derived> constexpr auto insert(typename D::const_iterator, typename D::size_type, typename D::value_type const &) noexcept(noexcept(std::declval< D & >().insert(pos, detail::make_n_iter(x, n), detail::make_n_iter_end(x, n))))); template<typename D = Derived> constexpr auto insert(typename D::const_iterator, std::initializer_list< typename D::value_type >) noexcept(noexcept(std::declval< D & >() .insert(pos, il.begin(), il.end())))); template<typename D = Derived> constexpr auto erase(typename D::const_iterator) noexcept; template<typename InputIterator, typename D = Derived, typename Enable = std::enable_if_t<v1_dtl::in_iter<InputIterator>::value> > constexpr auto assign(InputIterator, InputIterator) noexcept(noexcept(std::declval< D & >().insert(std::declval< D & >().begin(), first, last)))); template<typename D = Derived> constexpr auto assign(typename D::size_type, typename D::value_type const &) noexcept(noexcept(std::declval< D & >() .insert(std::declval< D & >().begin(), detail::make_n_iter(x, n), detail::make_n_iter_end(x, n))))); template<typename D = Derived> constexpr auto assign(std::initializer_list< typename D::value_type >) noexcept(noexcept(std::declval< D & >().assign(il.begin(), il.end())))); template<typename D = Derived> constexpr auto clear() noexcept; };
A CRTP template that one may derive from to make it easier to define container types.
The template parameter D
for sequence_container_interface
may be an incomplete type. Before any member of the resulting specialization of sequence_container_interface
other than special member functions is referenced, D
shall be complete; shall model std::derived_from<sequence_container_interface<D>>
, std::semiregular
, and std::forward_range
; and shall contain all the nested types required in Table 72: Container requirements and, for those whose iterator nested type models std::bidirectinal_iterator
, those in Table 73: Reversible container requirements.
For an object d
of type D
, a call to std::ranges::begin(d)
sxhall not mutate any data members of d
, and d
's destructor shall end the lifetimes of the objects in [std::ranges::begin(d), std::ranges::end(d))
.
sequence_container_interface
public member functionstemplate<typename D = Derived> constexpr auto empty() noexcept(noexcept(std::declval< D & >().begin()==std::declval< D & >().end())));
template<typename D = Derived> constexpr auto empty() const noexcept(noexcept(std::declval< D const & >().begin()==std::declval< D const & >().end())));
template<typename D = Derived, element_layout C = Contiguity, typename Enable = std::enable_if_t<C == element_layout::contiguous> > constexpr auto data() noexcept(noexcept(std::declval< D & >().begin())));
template<typename D = Derived, element_layout C = Contiguity, typename Enable = std::enable_if_t<C == element_layout::contiguous> > constexpr auto data() const noexcept(noexcept(std::declval< D const & >().begin())));
template<typename D = Derived> constexpr auto size() noexcept(noexcept(std::declval< D & >().end() - std::declval< D & >().begin())));
template<typename D = Derived> constexpr auto size() const noexcept(noexcept(std::declval< D const & >().end() - std::declval< D const & >().begin())));
template<typename D = Derived> constexpr auto front() noexcept(noexcept(*std::declval< D & >().begin())));
template<typename D = Derived> constexpr auto front() const noexcept(noexcept(*std::declval< D const & >().begin())));
template<typename D = Derived> constexpr auto push_front(typename D::value_type const & x) noexcept(noexcept(std::declval< D & >().emplace_front(x))));
template<typename D = Derived> constexpr auto push_front(typename D::value_type && x) noexcept(noexcept(std::declval< D & >().emplace_front(std::move(x)))));
template<typename D = Derived> constexpr auto pop_front() noexcept;
template<typename D = Derived, typename Enable = std::enable_if_t< v1_dtl::decrementable_sentinel<D>::value && v1_dtl::common_range<D>::value> > constexpr auto back() noexcept(noexcept(*std::prev(std::declval< D & >().end()))));
template<typename D = Derived, typename Enable = std::enable_if_t< v1_dtl::decrementable_sentinel<D>::value && v1_dtl::common_range<D>::value> > constexpr auto back() const noexcept(noexcept(*std::prev(std::declval< D const & >().end()))));
template<typename D = Derived> constexpr auto push_back(typename D::value_type const & x) noexcept(noexcept(std::declval< D & >().emplace_back(x))));
template<typename D = Derived> constexpr auto push_back(typename D::value_type && x) noexcept(noexcept(std::declval< D & >().emplace_back(std::move(x)))));
template<typename D = Derived> constexpr auto pop_back() noexcept;
template<typename D = Derived> constexpr auto operator[](typename D::size_type n) noexcept(noexcept(std::declval< D & >().begin()[n])));
template<typename D = Derived> constexpr auto operator[](typename D::size_type n) const noexcept(noexcept(std::declval< D const & >().begin()[n])));
template<typename D = Derived> constexpr auto at(typename D::size_type i);
template<typename D = Derived> constexpr auto at(typename D::size_type i) const;
template<typename D = Derived, typename Iter = typename D::const_iterator> constexpr Iter begin() const noexcept(noexcept(std::declval< D & >().begin())));
template<typename D = Derived, typename Iter = typename D::const_iterator> constexpr Iter end() const noexcept(noexcept(std::declval< D & >().end())));
template<typename D = Derived> constexpr auto cbegin() const noexcept(noexcept(std::declval< D const & >().begin())));
template<typename D = Derived> constexpr auto cend() const noexcept(noexcept(std::declval< D const & >().end())));
template<typename D = Derived, typename Enable = std::enable_if_t<v1_dtl::common_range<D>::value> > constexpr auto rbegin() noexcept(noexcept(stl_interfaces::make_reverse_iterator(std::declval< D & >().end()))));
template<typename D = Derived, typename Enable = std::enable_if_t<v1_dtl::common_range<D>::value> > constexpr auto rend() noexcept(noexcept(stl_interfaces::make_reverse_iterator(std::declval< D & >().begin()))));
template<typename D = Derived> constexpr auto rbegin() const noexcept(noexcept(std::declval< D & >().rbegin())));
template<typename D = Derived> constexpr auto rend() const noexcept(noexcept(std::declval< D & >().rend())));
template<typename D = Derived> constexpr auto crbegin() const noexcept(noexcept(std::declval< D const & >().rbegin())));
template<typename D = Derived> constexpr auto crend() const noexcept(noexcept(std::declval< D const & >().rend())));
template<typename D = Derived> constexpr auto insert(typename D::const_iterator pos, typename D::value_type const & x) noexcept(noexcept(std::declval< D & >().emplace(pos, x))));
template<typename D = Derived> constexpr auto insert(typename D::const_iterator pos, typename D::value_type && x) noexcept(noexcept(std::declval< D & >() .emplace(pos, std::move(x)))));
template<typename D = Derived> constexpr auto insert(typename D::const_iterator pos, typename D::size_type n, typename D::value_type const & x) noexcept(noexcept(std::declval< D & >().insert(pos, detail::make_n_iter(x, n), detail::make_n_iter_end(x, n)))));
template<typename D = Derived> constexpr auto insert(typename D::const_iterator pos, std::initializer_list< typename D::value_type > il) noexcept(noexcept(std::declval< D & >() .insert(pos, il.begin(), il.end()))));
template<typename D = Derived> constexpr auto erase(typename D::const_iterator pos) noexcept;
template<typename InputIterator, typename D = Derived, typename Enable = std::enable_if_t<v1_dtl::in_iter<InputIterator>::value> > constexpr auto assign(InputIterator first, InputIterator last) noexcept(noexcept(std::declval< D & >().insert(std::declval< D & >().begin(), first, last))));
template<typename D = Derived> constexpr auto assign(typename D::size_type n, typename D::value_type const & x) noexcept(noexcept(std::declval< D & >() .insert(std::declval< D & >().begin(), detail::make_n_iter(x, n), detail::make_n_iter_end(x, n)))));
template<typename D = Derived> constexpr auto assign(std::initializer_list< typename D::value_type > il) noexcept(noexcept(std::declval< D & >().assign(il.begin(), il.end()))));
template<typename D = Derived> constexpr auto clear() noexcept;