6 #ifndef KAGOME_COMMON_SIZELIMITEDCONTAINER     7 #define KAGOME_COMMON_SIZELIMITEDCONTAINER     9 #include <fmt/format.h>    13 #include <type_traits>    17 #if __has_builtin(__builtin_expect)    18 #define unlikely(x) __builtin_expect((x), 0)    22 #define unlikely(x) (x)    29     template <
typename... Args>
    31         : 
std::length_error(
fmt::format(
std::forward<Args>(args)...)) {}
    34   template <
typename BaseContainer, std::
size_t MaxSize>
    37     using Base = BaseContainer;
    38     using Span = gsl::span<typename Base::value_type>;
    40     static constexpr 
bool size_check_is_enabled =
    41         MaxSize < std::numeric_limits<typename Base::size_type>::max();
    45     static constexpr 
bool is_static_collection = 
false;
    47     [[nodiscard]] 
inline constexpr 
typename Base::size_type 
max_size() {
    55             if constexpr (size_check_is_enabled) {
    58                     "Destination has limited size by {}; requested size is {}",
    68             if constexpr (size_check_is_enabled) {
    71                     "Destination has limited size by {}; requested size is {}",
    76             return Base(size, value);
    81             if constexpr (size_check_is_enabled) {
    82               if (
unlikely(other.size() > max_size())) {
    84                     "Destination has limited size by {}; Source size is {}",
    94             if constexpr (size_check_is_enabled) {
    95               if (
unlikely(other.size() > max_size())) {
    97                     "Destination has limited size by {}; Source size is {}",
   102             return std::move(other);
   105     template <
typename Iter,
   106               typename = std::enable_if_t<std::is_base_of_v<
   107                   std::input_iterator_tag,
   108                   typename std::iterator_traits<Iter>::iterator_category>>>
   111             if constexpr (size_check_is_enabled) {
   112               const size_t size = std::distance(begin, end);
   115                     "Container has limited size by {}; Source range size is {}",
   120             return Base(std::move(begin), std::move(end));
   127       if constexpr (size_check_is_enabled) {
   128         if (
unlikely(other.size() > max_size())) {
   130               "Destination has limited size by {}; Source size is {}",
   135       static_cast<Base &
>(*this) = other;
   140       if constexpr (size_check_is_enabled) {
   141         if (
unlikely(other.size() > max_size())) {
   143               "Destination has limited size by {}; Source size is {}",
   148       static_cast<Base &
>(*this) = std::move(other);
   153         std::initializer_list<typename Base::value_type> list) {
   154       if constexpr (size_check_is_enabled) {
   155         if (
unlikely(list.size() > max_size())) {
   157               "Destination has limited size by {}; Source size is {}",
   162       static_cast<Base &
>(*this) =
   163           std::forward<std::initializer_list<typename Base::value_type>>(list);
   167     void assign(
typename Base::size_type size,
   168                 const typename Base::value_type &value) {
   169       if constexpr (size_check_is_enabled) {
   172               "Destination has limited size by {}; Requested size is {}",
   177       return Base::assign(size, value);
   180     template <
typename Iter,
   181               typename = std::enable_if_t<std::is_base_of_v<
   182                   std::input_iterator_tag,
   183                   typename std::iterator_traits<Iter>::iterator_category>>>
   185       if constexpr (size_check_is_enabled) {
   186         const size_t size = std::distance(begin, end);
   189               "Container has limited size by {}; Source range size is {}",
   194       return Base::assign(std::move(begin), std::move(end));
   197     void assign(std::initializer_list<typename Base::value_type> list) {
   198       if constexpr (size_check_is_enabled) {
   199         if (
unlikely(list.size() > max_size())) {
   201               "Container has limited size by {}; Source range size is {}",
   206       return Base::assign(std::move(list));
   209     template <
typename... Args>
   211       if constexpr (size_check_is_enabled) {
   212         if (
unlikely(Base::size() >= max_size())) {
   214               "Container has limited size by {}; Size is already {} ",
   219       return Base::emplace_back(std::forward<Args>(args)...);
   225         bool isIter = std::is_same_v<Iter, typename Base::iterator>,
   226         bool isConstIter = std::is_same_v<Iter, typename Base::const_iterator>,
   227         typename = std::enable_if_t<isIter or isConstIter>>
   228     typename Base::iterator 
emplace(Iter pos, Args &&...args) {
   229       if constexpr (size_check_is_enabled) {
   230         if (
unlikely(Base::size() >= max_size())) {
   232               "Container has limited size by {}; Size is already {} ",
   237       return Base::emplace(std::move(pos), std::forward<Args>(args)...);
   242         bool isIter = std::is_same_v<Iter, typename Base::iterator>,
   243         bool isConstIter = std::is_same_v<Iter, typename Base::const_iterator>,
   244         typename = std::enable_if_t<isIter or isConstIter>>
   246                                    const typename Base::value_type &value) {
   247       if constexpr (size_check_is_enabled) {
   248         if (
unlikely(Base::size() >= max_size())) {
   250               "Destination has limited size by {}; Size is already {} ",
   255       return Base::insert(std::move(pos), value);
   260         bool isIter = std::is_same_v<Iter, typename Base::iterator>,
   261         bool isConstIter = std::is_same_v<Iter, typename Base::const_iterator>,
   262         typename = std::enable_if_t<isIter or isConstIter>>
   264                                    typename Base::size_type size,
   265                                    const typename Base::value_type &value) {
   266       if constexpr (size_check_is_enabled) {
   267         const auto available = max_size() - Base::size();
   270               "Destination has limited size by {}; Requested size is {}",
   275       return Base::insert(std::move(pos), size, value);
   281         bool isIter = std::is_same_v<OutIt, typename Base::iterator>,
   282         bool isConstIter = std::is_same_v<OutIt, typename Base::const_iterator>,
   283         typename = std::enable_if_t<isIter or isConstIter>,
   284         typename = std::enable_if_t<std::is_base_of_v<
   285             std::input_iterator_tag,
   286             typename std::iterator_traits<InIt>::iterator_category>>>
   287     typename Base::iterator 
insert(OutIt pos, InIt begin, InIt end) {
   288       if constexpr (size_check_is_enabled) {
   289         const size_t size = std::distance(begin, end);
   290         const auto available = max_size() - Base::size();
   293               "Destination has limited size by {} and current size is {}; "   294               "Source range size is {} and would overflow destination",
   300       return Base::insert(std::move(pos), std::move(begin), std::move(end));
   305         bool isIter = std::is_same_v<Iter, typename Base::iterator>,
   306         bool isConstIter = std::is_same_v<Iter, typename Base::const_iterator>,
   307         typename = std::enable_if_t<isIter or isConstIter>>
   309         Iter pos, std::initializer_list<typename Base::value_type> &&list) {
   310       if constexpr (size_check_is_enabled) {
   311         const auto available = max_size() - Base::size();
   312         if (
unlikely(available < list.size())) {
   314               "Container has limited size by {}; Source range size is {}",
   319       return Base::insert(pos, std::move(list));
   322     template <
typename V>
   324       if constexpr (size_check_is_enabled) {
   325         if (
unlikely(Base::size() >= max_size())) {
   327               "Container has limited size by {}; Size is already maximum",
   331       Base::push_back(std::forward<V>(value));
   335       if constexpr (size_check_is_enabled) {
   338               "Destination has limited size by {}; Requested size is {}",
   343       return Base::reserve(size);
   346     void resize(
typename Base::size_type size) {
   347       if constexpr (size_check_is_enabled) {
   350               "Destination has limited size by {}; Requested size is {}",
   355       return Base::resize(size);
   358     void resize(
typename Base::size_type size,
   359                 const typename Base::value_type &value) {
   360       if constexpr (size_check_is_enabled) {
   363               "Destination has limited size by {}; Requested size is {}",
   368       return Base::resize(size, value);
   373           Base::cbegin(), Base::cend(), other.cbegin(), other.cend());
   378           Base::cbegin(), Base::cend(), other.cbegin(), other.cend());
   382       return not(*
this == other);
   386       return not(*
this == other);
   390       return std::lexicographical_compare(
   391           Base::cbegin(), Base::cend(), other.cbegin(), other.cend());
   395       return std::lexicographical_compare(
   396           Base::cbegin(), Base::cend(), other.cbegin(), other.cend());
   400   template <
typename ElementType, 
size_t MaxSize, 
typename... Args>
   408 #endif  // KAGOME_COMMON_SIZELIMITEDCONTAINER Base::iterator insert(Iter pos, const typename Base::value_type &value)
 
void resize(typename Base::size_type size)
 
SizeLimitedContainer(size_t size)
 
gsl::span< typename Base::value_type > Span
 
SizeLimitedContainer(std::initializer_list< typename Base::value_type > list)
 
SizeLimitedContainer & operator=(std::initializer_list< typename Base::value_type > list)
 
SizeLimitedContainer & operator=(const Base &other)
 
bool operator!=(const Base &other) const noexcept
 
bool operator<(const Span &other) const noexcept
 
Base::reference & emplace_back(Args &&...args)
 
void assign(std::initializer_list< typename Base::value_type > list)
 
bool operator!=(const Span &other) const noexcept
 
constexpr Base::size_type max_size()
 
bool operator==(const Span &other) const noexcept
 
void push_back(V &&value)
 
void assign(Iter begin, Iter end)
 
void reserve(typename Base::size_type size)
 
SizeLimitedContainer(const Base &other)
 
SizeLimitedContainer(size_t size, const typename Base::value_type &value)
 
bool operator==(const Base &other) const noexcept
 
void resize(typename Base::size_type size, const typename Base::value_type &value)
 
MaxSizeException(Args &&...args)
 
SizeLimitedContainer & operator=(Base &&other)
 
SizeLimitedContainer(Base &&other)
 
Base::iterator insert(Iter pos, typename Base::size_type size, const typename Base::value_type &value)
 
Base::iterator insert(Iter pos, std::initializer_list< typename Base::value_type > &&list)
 
SizeLimitedContainer(Iter begin, Iter end)
 
Base::iterator insert(OutIt pos, InIt begin, InIt end)
 
bool operator<(const Base &other) const noexcept
 
Base::iterator emplace(Iter pos, Args &&...args)
 
void assign(typename Base::size_type size, const typename Base::value_type &value)