iffl  1.3.4
Implements Intrusive Flat Forward List container
iffl_common.h
Go to the documentation of this file.
1 #pragma once
2 
12 
13 #include <type_traits>
14 #include <vector>
15 #include <tuple>
16 #include <algorithm>
17 #include <utility>
18 #include <atomic>
19 #include <cerrno>
20 #include <typeinfo>
21 #include <memory>
22 #include <cstring>
23 
24 #if defined(__GNUC__) || defined(__clang__)
25 #include <experimental/memory_resource>
29 #define FFL_PMR std::experimental::pmr
30 #else
31 #include <memory_resource>
35 #define FFL_PMR std::pmr
36 #endif
37 
38 #include <cstdio>
39 
40 #if defined(__GNUC__) || defined(__clang__)
41 #define FFL_UNALIGNED __attribute__ ((__packed__))
46 #else
47 #if defined(_M_IX86 )
53 #define FFL_UNALIGNED
54 #else
55 #define FFL_UNALIGNED __unaligned
56 #endif
57 
58 #endif
59 
60 #if defined(__GNUC__) || defined(__clang__)
61 //#include <x86intrin.h>
65 #define FFL_PLATFORM_FAIL_FAST(EC) {std::terminate();}
66 #else
67 #include <intrin.h>
71 #define FFL_PLATFORM_FAIL_FAST(EC) {__debugbreak();__fastfail(EC);}
72 #endif
73 
74 #if defined(__GNUC__) || defined(__clang__)
75 #define FFL_ALLIGNED_ALLOC(BYTES, ALIGNMENT) malloc(BYTES)
80 #define FFL_ALLIGNED_FREE(PTR) free(PTR)
84 #else
85 #define FFL_ALLIGNED_ALLOC(BYTES, ALIGNMENT) _aligned_malloc(BYTES, ALIGNMENT)
89 #define FFL_ALLIGNED_FREE(PTR) _aligned_free(PTR)
93 #endif
94 
99 #ifndef FFL_FAST_FAIL
100 #define FFL_FAST_FAIL(EC) {FFL_PLATFORM_FAIL_FAST(EC);}
101 #endif
102 #ifndef FFL_CRASH_APPLICATION
106 #define FFL_CRASH_APPLICATION() FFL_FAST_FAIL(ENOTRECOVERABLE)
107 #endif
108 #ifndef FFL_CODDING_ERROR_IF
113 #define FFL_CODDING_ERROR_IF(C) if (C) {FFL_FAST_FAIL(ENOTRECOVERABLE);} else {;}
114 #endif
115 #ifndef FFL_CODDING_ERROR_IF_NOT
120 #define FFL_CODDING_ERROR_IF_NOT(C) if (C) {;} else {FFL_FAST_FAIL(ENOTRECOVERABLE);}
121 #endif
122 
128 #define FFL_FIELD_OFFSET(T, F) (((char const *)(&((T *)nullptr)->F)) - (char const *)nullptr)
129 #define FFL_SIZE_THROUGH_FIELD(T, F) (FFL_FIELD_OFFSET(T, F) + sizeof(((T *)nullptr)->F))
136 #define FFL_PADDING_OFFSET_AFTER_FIELD(T, F) FFL_SIZE_THROUGH_FIELD(T, F)
142 #define FFL_PADDING_BETWEEN_FIELDS_UNSAFE(T, F1, F2)(FFL_FIELD_OFFSET(T, F2) - FFL_SIZE_THROUGH_FIELD(T, F1))
150 #define FFL_PADDING_BETWEEN_FIELDS(T, F1, F2)([] {static_assert(FFL_FIELD_OFFSET(T, F1) <= FFL_FIELD_OFFSET(T, F2), "F1 must have lower offset in structure than F2"); }, FFL_PADDING_BETWEEN_FIELDS_UNSAFE(T, F1, F2))
158 //
165 #define FFL_FIELD_PTR_TO_OBJ_PTR(T, F, P) ((T *)((char const *)(P) - FFL_FIELD_OFFSET(T, F)))
166 
171 namespace iffl {
172 
179 #ifdef min
180 #define FFL_SAVED_MIN_DEFINITION min
181 #undef min
182 #endif
183 
184 #ifdef max
185 #define FFL_SAVED_MAX_DEFINITION max
186 #undef max
187 #endif
188  inline static size_t const npos = std::numeric_limits<size_t>::max();
194 
198 #ifdef FFL_SAVED_MAX_DEFINITION
199 #define max FFL_SAVED_MAX_DEFINITION
200 #undef FFL_SAVED_MAX_DEFINITION
201 #endif
202 
203 #ifdef FFL_SAVED_MIN_DEFINITION
204 #define min FFL_SAVED_MIN_DEFINITION
205 #undef FFL_SAVED_MIN_DEFINITION
206 #endif
207 
215 template<typename T>
216 constexpr inline void unused_variable([[maybe_unused]] T const &) {
217 }
222 template<typename T>
223 constexpr inline void unused_expression_result([[maybe_unused]] T const &) {
224 }
225 
231  inline size_t const ptr_to_size(void const *const ptr) {
232  static_assert(sizeof(void*) == sizeof(size_t),
233  "This function assumes that on this platform size of pointer equals to a size of size_t type");
234  size_t const *const size_ptr = reinterpret_cast<size_t const *const>(&ptr);
235  return *size_ptr;
236  }
237 
243  inline void * const size_to_ptr(size_t size) {
244  static_assert(sizeof(void*) == sizeof(size_t),
245  "This function assumes that on this platform size of pointer equals to a size of size_t type");
246  void ** ptr_ptr = reinterpret_cast<void **>(&size);
247  return *ptr_ptr;
248  }
255  constexpr inline size_t roundup_size_to_alignment(size_t size, size_t alignment) noexcept {
256  return alignment ? ((size + alignment - 1) / alignment) *alignment : size;
257  }
264  template<typename T>
265  constexpr inline size_t roundup_size_to_alignment(size_t size) noexcept {
266  static_assert(alignof(T) > 0, "Cannot divide by 0");
267  return roundup_size_to_alignment(size, alignof(T));
268  }
275  inline void * roundup_ptr_to_alignment(void * ptr, size_t alignment) noexcept {
276  return static_cast<void *>(size_to_ptr(roundup_size_to_alignment(ptr_to_size(ptr), alignment)));
277  }
284  template<typename T>
285  inline void * roundup_ptr_to_alignment(void *ptr) noexcept {
286  static_assert(alignof(T) > 0, "Cannot divide by 0");
287  return roundup_ptr_to_alignment(ptr, alignof(T));
288  }
295  inline void const * roundup_ptr_to_alignment(void const *ptr, size_t alignment) noexcept {
296  return static_cast<void const *>(size_to_ptr(roundup_size_to_alignment(ptr_to_size(ptr), alignment)));
297  }
304  template<typename T>
305  inline void const * roundup_ptr_to_alignment(void const *ptr) noexcept {
306  static_assert(alignof(T) > 0, "Cannot divide by 0");
307  return roundup_ptr_to_alignment(ptr, alignof(T));
308  }
316  inline void copy_data(char *to_buffer, char const *from_buffer, size_t length) noexcept {
317  std::memcpy(to_buffer, from_buffer, length);
318  }
326 
327  inline void move_data(char *to_buffer, char const *from_buffer, size_t length) noexcept {
328  std::memmove(to_buffer, from_buffer, length);
329  }
336  inline void fill_buffer(char *buffer, int value, size_t length) noexcept {
337  std::memset(buffer, value, length);
338  }
344  inline void zero_buffer(char *buffer, size_t length) noexcept {
345  fill_buffer(buffer, 0, length);
346  }
352  inline size_t distance(void const *begin, void const *end) noexcept {
354  return (static_cast<char const *>(end) - static_cast<char const *>(begin));
355  }
361  template <typename T>
362  inline char *cast_to_char_ptr(T *p) noexcept {
363  if constexpr (std::is_const_v<T>) {
364  return const_cast<char *>(reinterpret_cast<char const *>(p));
365  } else {
366  return reinterpret_cast<char *>(p);
367  }
368  }
374  template <typename T>
375  inline void *cast_to_void_ptr(T *p) noexcept {
376  if constexpr (std::is_const_v<T>) {
377  return const_cast<void *>(reinterpret_cast<void const *>(p));
378  } else {
379  return reinterpret_cast<void *>(p);
380  }
381  }
397  template <typename G>
398  class scope_guard :private G {
399 
400  public:
405  explicit constexpr scope_guard(G const &g)
406  : G{ g } {
407  }
412  explicit constexpr scope_guard(G &&g)
413  : G{ std::move(g) } {
414  }
418  constexpr scope_guard(scope_guard &&) = default;
422  constexpr scope_guard &operator=(scope_guard &&) = default;
426  constexpr scope_guard(scope_guard &) = delete;
430  constexpr scope_guard &operator=(scope_guard &) = delete;
434  ~scope_guard() noexcept {
435  discharge();
436  }
440  void discharge() noexcept {
441  if (armed_) {
442  this->G::operator()();
443  armed_ = false;
444  }
445  }
449  constexpr void disarm() noexcept {
450  armed_ = false;
451  }
455  constexpr void arm() noexcept {
456  armed_ = true;
457  }
462  constexpr bool is_armed() const noexcept {
463  return armed_;
464  }
469  constexpr explicit operator bool() const noexcept {
470  return is_armed();
471  }
472 
473  private:
477  bool armed_{ true };
478  };
479 
488  template <typename G>
489  inline constexpr auto make_scope_guard(G &&g) {
490  return scope_guard<G>{std::forward<G>(g)};
491  }
492 
500  struct attach_buffer {};
501 
524  struct range {
530  size_t buffer_begin{ 0 };
534  size_t data_end{ 0 };
539  size_t buffer_end{ 0 };
544  constexpr size_t begin() const {
545  return buffer_begin;
546  }
550  constexpr void verify() const noexcept {
552  data_end <= buffer_end);
553  }
558  constexpr size_t data_size() const noexcept {
559  return data_end - buffer_begin;
560  }
565  constexpr size_t buffer_size() const noexcept {
566  return buffer_end - buffer_begin;
567  }
572  constexpr size_t unused_capacity() const noexcept {
573  return buffer_end - data_end;
574  }
580  void fill_unused_capacity_data_ptr(char *data_ptr, int fill_byte) const noexcept {
581  fill_buffer(data_ptr + data_size(),
582  fill_byte,
583  unused_capacity());
584  }
589  void zero_unused_capacity_data_ptr(char *data_ptr) const noexcept {
590  fill_unused_capacity_data_ptr(data_ptr, 0);
591  }
597  void fill_unused_capacity_container_ptr(char *container_ptr, int fill_byte) const noexcept {
598  fill_unused_capacity_data_ptr(container_ptr + buffer_begin, fill_byte);
599  }
604  void zero_unused_capacity_container_ptr(char *container_ptr) const noexcept {
606  }
611  constexpr bool buffer_contains(size_t position) const noexcept {
612  return buffer_begin <= position && position < buffer_end;
613  }
618  constexpr bool data_contains(size_t position) const noexcept {
619  return buffer_begin <= position && position < data_end;
620  }
621  };
622 
631  template<size_t ALIGNMENT_V>
632  struct range_with_alighment : public range {
636  constexpr static size_t const alignment{ ALIGNMENT_V };
641  constexpr size_t data_end_aligned() const noexcept {
642  return roundup_size_to_alignment(data_end, ALIGNMENT_V);
643  }
648  constexpr size_t buffer_end_aligned() const noexcept {
649  return roundup_size_to_alignment(buffer_end, ALIGNMENT_V);
650  }
654  constexpr size_t data_size_padded() const noexcept {
655  //
656  // current element size if we also add padding
657  // to keep next element aligned
658  //
659  return data_end_aligned() - begin();
660  }
664  constexpr size_t required_data_padding() const noexcept {
665  //
666  // Size of required data padding
667  //
668  return data_end_aligned() - data_end;
669  }
673  constexpr size_t required_buffer_padding() const noexcept {
674  //
675  // Size of required data padding
676  //
677  return buffer_end_aligned() - buffer_end;
678  }
682  constexpr size_t buffer_size_padded() const noexcept {
683  return buffer_end_aligned() - begin();
684  }
685  };
692  template<size_t ALIGNMENT_V>
697  constexpr static size_t const alignment{ ALIGNMENT_V };
701  size_t offset{ 0 };
705  constexpr size_t offset_aligned() const noexcept {
706  return roundup_size_to_alignment(offset, ALIGNMENT_V);
707  }
711  constexpr size_t padding_size() const noexcept {
712  return offset_aligned() - offset;
713  }
714  };
721  template<size_t ALIGNMENT_V>
726  constexpr static size_t const alignment{ ALIGNMENT_V };
730  size_t size{ 0 };
734  constexpr size_t size_padded() const noexcept {
735  return roundup_size_to_alignment(size, ALIGNMENT_V);
736  }
740  constexpr size_t padding_size() const noexcept {
741  return size_padded() - size;
742  }
743  };
744 
749  template<size_t ALIGNMENT_V>
754  size_t total_capacity{ 0 };
763  return { last_element.data_end };
764  }
769  constexpr size_t remaining_capacity_for_insert() const {
770  return total_capacity - used_capacity().size;
771  }
775  //
776  constexpr size_t remaining_capacity_for_append() const {
777  if (total_capacity <= used_capacity().size_padded()) {
778  return 0;
779  } else {
780  return total_capacity - used_capacity().size_padded();
781  }
782  }
783  };
784 
791  };
792 
799  };
800 
817  template<class T1,
818  class T2,
819  bool = std::is_empty_v<T1> && !std::is_final_v<T1>>
820  class compressed_pair final : private T1 {
821  public:
822 
832  template<class... P>
834  P&&... p)
835  : T1()
836  , v2_(std::forward<P>(p)...) {
837  }
849  template<class P1,
850  class... P2>
852  P1&& p1,
853  P2&&... p2)
854  : T1(std::forward<P1>(p1))
855  , v2_(std::forward<P2>(p2)...) {// construct from forwarded values
856  }
861  constexpr T1& get_first() noexcept {
862  return (*this);
863  }
868  constexpr T1 const & get_first() const noexcept {
869  return (*this);
870  }
875  constexpr T2& get_second() noexcept {
876  return (v2_);
877  }
882  constexpr T2 const & get_second() const noexcept {
883  return (v2_);
884  }
885 
886  private:
891  T2 v2_;
892  };
893 
905  template<class T1,
906  class T2>
907  class compressed_pair<T1, T2, false> final {
908  public:
909 
919  template<class... P>
921  P&&... p)
922  : v1_()
923  , v2_(std::forward<P>(p)...) {// construct from forwarded values
924  }
925 
937  template<class P1,
938  class... P2>
940  P1&& p1,
941  P2&&... p2)
942  : v1_(std::forward<P1>(p1))
943  , v2_(std::forward<P2>(p2)...) {
944  }
949  constexpr T1& get_first() noexcept {
950  return (v1_);
951  }
956  constexpr T1 const & get_first() const noexcept {
957  return (v1_);
958  }
963  constexpr T2& get_second() noexcept {
964  return (v2_);
965  }
970  constexpr T2 const & get_second() const noexcept {
971  return (v2_);
972  }
973 
974  private:
975  T1 v1_;
976  T2 v2_;
977  };
983  template <typename T = char>
984  struct buffer_t {
985  //
986  // Buffer pointer can be const and non-const buffer
987  //
988  static_assert(std::is_same_v<T, char> || std::is_same_v<T, char const>,
989  "buffer pointer can be char * or char const *");
993  inline static bool const is_const{ std::is_same_v<T, char const> };
997  buffer_t() = default;
1001  buffer_t(buffer_t const &) = default;
1005  buffer_t &operator= (buffer_t const &) = default;
1011  template<typename V,
1012  typename = std::enable_if<std::is_assignable_v<T*, V*>>>
1013  buffer_t(buffer_t<V> const &buff) {
1014  begin = buff.begin;
1015  last = buff.last;
1016  end = buff.end;
1017  }
1023  template<typename V,
1024  typename = std::enable_if<std::is_assignable_v<T*, V*>>>
1026  begin = buff.begin;
1027  last = buff.last;
1028  end = buff.end;
1029  return *this;
1030  }
1034  buffer_t(T *begin, T *last, T *end) noexcept
1035  : begin{ begin }
1036  , last{ last }
1037  , end{ end } {
1038 
1039  validate();
1040  }
1044  buffer_t(T *begin, size_t *last_offset, T *end_offset) noexcept
1045  : begin{ begin }
1046  , last{ begin + last_offset }
1047  , end{ begin + end_offset } {
1048 
1049  validate();
1050  }
1055  using value_type = T;
1060  using pointer_type = T *;
1065  using refernce_type = T & ;
1070  using size_type = size_t;
1075  pointer_type begin{ nullptr };
1081  pointer_type last{ nullptr };
1086  pointer_type end{ nullptr };
1091  constexpr void set_begin(pointer_type new_begin) noexcept {
1092  size_type tmp_last_offset = last_offset();
1093  size_type tmp_size = size();
1094  begin = new_begin;
1095  set_size_unsafe(tmp_size);
1096  set_last_offset_unsafe(tmp_last_offset);
1097  }
1101  constexpr size_type size() const noexcept {
1102  return end ? end - begin
1103  : 0;
1104  }
1109  constexpr void set_size_unsafe(size_type size) noexcept {
1110  end = begin + size;
1111  }
1116  constexpr void set_size(size_type size) noexcept {
1118  validate();
1119  }
1123  constexpr size_type last_offset() const noexcept {
1124  return last ? last - begin
1125  : iffl::npos;
1126  }
1131  constexpr void set_last_offset_unsafe(size_type offset) noexcept {
1132  last = (iffl::npos == offset ? nullptr
1133  : begin + offset);
1134  }
1140  constexpr void set_last_offset(size_type offset) noexcept {
1141  set_last_offset_unsafe(offset);
1142  validate();
1143  }
1146  constexpr void validate() const noexcept {
1147  //
1148  // empty() calls this method so we cannot call it here
1149  //
1150  if (nullptr == last) {
1152  } else {
1154  }
1155  }
1159  constexpr void clear() noexcept {
1160  begin = nullptr;
1161  last = nullptr;
1162  end = nullptr;
1163  }
1167  constexpr void forget_last() noexcept {
1168  last = nullptr;
1169  }
1173  constexpr explicit operator bool() const noexcept {
1174  return begin != nullptr;
1175  }
1176  };
1187 
1188 } // namespace iffl
buffer_value_type * pointer_type
Pinter to the buffer elements.
Definition: iffl_common.h:1060
buffer_value_type value_type
type of buffer elements
Definition: iffl_common.h:1055
constexpr void clear() noexcept
Resets all pointers to nullptr.
Definition: iffl_common.h:1159
range_with_alighment< ALIGNMENT_V > last_element
Last element range.
Definition: iffl_common.h:758
constexpr T2 & get_second() noexcept
Returns a reference to the second element of compressed pair.
Definition: iffl_common.h:875
constexpr size_t buffer_size_padded() const noexcept
Definition: iffl_common.h:682
void zero_buffer(char *buffer, size_t length) noexcept
sets "length" consecutive bytes of "to_buffer" to 0.
Definition: iffl_common.h:344
constexpr T2 & get_second() noexcept
Definition: iffl_common.h:963
constexpr T1 & get_first() noexcept
Definition: iffl_common.h:949
constexpr T2 const & get_second() const noexcept
Returns a const reference to the second element of compressed pair.
Definition: iffl_common.h:882
constexpr scope_guard(G &&g)
Constructor from an instance of functor.
Definition: iffl_common.h:412
char * cast_to_char_ptr(T *p) noexcept
Helper method to cast a pointer to a char *.
Definition: iffl_common.h:362
void discharge() noexcept
Use this method to discharge guard now.
Definition: iffl_common.h:440
constexpr size_t required_data_padding() const noexcept
Definition: iffl_common.h:664
constexpr size_t begin() const
Offset of the element buffer begin in a larger buffer.
Definition: iffl_common.h:544
pointer_type begin
Pointer to the beginning of buffer nullptr if no buffer.
Definition: iffl_common.h:1075
buffer_t(T *begin, size_t *last_offset, T *end_offset) noexcept
Assignment operator to const buffer from pointers.
Definition: iffl_common.h:1044
constexpr compressed_pair(one_then_variadic_args_t, P1 &&p1, P2 &&... p2)
Constructor.
Definition: iffl_common.h:851
static bool const is_const
True if this is const buffer and false otherwise.
Definition: iffl_common.h:993
constexpr void set_size_unsafe(size_type size) noexcept
Updates buffer size.
Definition: iffl_common.h:1109
size_t buffer_begin
Starting offset of element in a buffer Element always starts at the beginning of the buffer.
Definition: iffl_common.h:530
constexpr compressed_pair(one_then_variadic_args_t, P1 &&p1, P2 &&... p2)
Constructor.
Definition: iffl_common.h:939
constexpr scope_guard & operator=(scope_guard &&)=default
Guard supports moving between scopes.
void *const size_to_ptr(size_t size)
Reinterprets size_t value as pointer to void.
Definition: iffl_common.h:243
constexpr T1 const & get_first() const noexcept
Returns a const reference to the first element of compressed pair.
Definition: iffl_common.h:868
void fill_buffer(char *buffer, int value, size_t length) noexcept
sets "length" consecutive bytes of "to_buffer" to "value".
Definition: iffl_common.h:336
size_t size_type
Size type.
Definition: iffl_common.h:1070
constexpr size_t buffer_end_aligned() const noexcept
Definition: iffl_common.h:648
constexpr auto make_scope_guard(G &&g)
Factory method for scoped_guard.
Definition: iffl_common.h:489
Helper class used as a parameter in flat_forward_list constructor to designate that it should take ow...
Definition: iffl_common.h:500
constexpr size_t data_size_padded() const noexcept
Definition: iffl_common.h:654
Tag type for constructing first from one argument, constructing second from remaining arguments.
Definition: iffl_common.h:798
constexpr size_t size_padded() const noexcept
Definition: iffl_common.h:734
void zero_unused_capacity_container_ptr(char *container_ptr) const noexcept
Zeros unused part of buffer.
Definition: iffl_common.h:604
flat_forward_list_ref< T, TT >::iterator begin(flat_forward_list_ref< T, TT > &c) noexcept
Definition: iffl_list.h:2406
size_t distance(void const *begin, void const *end) noexcept
sets "length" consecutive bytes of "to_buffer" to 0.
Definition: iffl_common.h:352
constexpr size_t data_size() const noexcept
Data size.
Definition: iffl_common.h:558
intrusive flat forward list
void zero_unused_capacity_data_ptr(char *data_ptr) const noexcept
Zeros unused part of buffer.
Definition: iffl_common.h:589
constexpr T1 const & get_first() const noexcept
Definition: iffl_common.h:956
constexpr void unused_expression_result([[maybe_unused]] T const &)
Silence sensitizers warning about unused result of expression.
Definition: iffl_common.h:223
size_t offset
Not padded offset in a buffer.
Definition: iffl_common.h:701
size_t size
Not padded size.
Definition: iffl_common.h:730
buffer_t(buffer_t< V > const &buff)
Constructors const buffer from non-const buffer.
Definition: iffl_common.h:1013
constexpr size_t remaining_capacity_for_append() const
Definition: iffl_common.h:776
constexpr size_type last_offset() const noexcept
Definition: iffl_common.h:1123
constexpr bool data_contains(size_t position) const noexcept
Tells if position falls into the data buffer.
Definition: iffl_common.h:618
constexpr size_t required_buffer_padding() const noexcept
Definition: iffl_common.h:673
static constexpr size_t const alignment
Element's type alignment requirements.
Definition: iffl_common.h:726
constexpr void unused_variable([[maybe_unused]] T const &)
Restore saved min and max definition.
Definition: iffl_common.h:216
size_t total_capacity
Size of buffer.
Definition: iffl_common.h:754
Empty Base Class Optimization EBCO helper.
Definition: iffl_common.h:820
static constexpr size_t const alignment
Definition: iffl_common.h:636
void move_data(char *to_buffer, char const *from_buffer, size_t length) noexcept
copies length bytes from from_buffer to to_buffer. source and destination buffers can overlap
Definition: iffl_common.h:327
constexpr compressed_pair(zero_then_variadic_args_t, P &&... p)
Constructor.
Definition: iffl_common.h:920
constexpr size_t padding_size() const noexcept
Definition: iffl_common.h:740
pointer_type end
Pointer to the end of buffer nullptr if no buffer.
Definition: iffl_common.h:1086
template class that can be parametrized with a functor or a lambda that it will call in destructor.
Definition: iffl_common.h:398
Vocabulary type that describes a sub-buffer in a larger buffer and portion of that sub-buffer actuall...
Definition: iffl_common.h:632
static constexpr size_t const alignment
Definition: iffl_common.h:697
constexpr void set_last_offset_unsafe(size_type offset) noexcept
Sets offset of the last pointer.
Definition: iffl_common.h:1131
constexpr size_t data_end_aligned() const noexcept
Definition: iffl_common.h:641
constexpr bool buffer_contains(size_t position) const noexcept
Tells if position falls into the buffer.
Definition: iffl_common.h:611
Vocabulary type that describes a sub-buffer in a larger buffer, and portion of that sub-buffer actual...
Definition: iffl_common.h:524
constexpr T1 & get_first() noexcept
Returns a reference to the first element of compressed pair.
Definition: iffl_common.h:861
constexpr size_t unused_capacity() const noexcept
Size of unused buffer.
Definition: iffl_common.h:572
constexpr void forget_last() noexcept
Sets pointer to last element to nullptr.
Definition: iffl_common.h:1167
void * roundup_ptr_to_alignment(void *ptr, size_t alignment) noexcept
Rounds up pointer to specified alignment.
Definition: iffl_common.h:275
constexpr void set_last_offset(size_type offset) noexcept
Sets offset of the last pointer.
Definition: iffl_common.h:1140
constexpr void set_begin(pointer_type new_begin) noexcept
Sets pointer to the buffer begin and recalculates last and end.
Definition: iffl_common.h:1091
flat_forward_list_ref< T, TT >::iterator end(flat_forward_list_ref< T, TT > &c) noexcept
Definition: iffl_list.h:2454
constexpr void disarm() noexcept
Disarming guard tells it not discharge during destruction.
Definition: iffl_common.h:449
void fill_unused_capacity_container_ptr(char *container_ptr, int fill_byte) const noexcept
Fills unused part of buffer with fill_byte.
Definition: iffl_common.h:597
size_t data_end
Offset in the buffer where data end.
Definition: iffl_common.h:534
A set of pointers describing state of the buffer containing flat forward list.
Definition: iffl_common.h:984
constexpr void verify() const noexcept
Fail fast if range invariants are broken.
Definition: iffl_common.h:550
buffer_t()=default
Default constructor.
void fill_unused_capacity_data_ptr(char *data_ptr, int fill_byte) const noexcept
Fills unused part of buffer with fill_byte.
Definition: iffl_common.h:580
constexpr size_t roundup_size_to_alignment(size_t size, size_t alignment) noexcept
Rounds up size to specified alignment.
Definition: iffl_common.h:255
constexpr bool is_armed() const noexcept
Tells if guard is armed.
Definition: iffl_common.h:462
~scope_guard() noexcept
Destructor attempts to call functor if guard was not disarmed.
Definition: iffl_common.h:434
size_t const ptr_to_size(void const *const ptr)
Reinterprets pointer to void value as size_t value.
Definition: iffl_common.h:231
void copy_data(char *to_buffer, char const *from_buffer, size_t length) noexcept
copies length bytes from from_buffer to to_buffer. source and destination buffers cannot overlap
Definition: iffl_common.h:316
size_t buffer_end
Offset of the end of the buffer Next element of the flat list starts at this offset.
Definition: iffl_common.h:539
buffer_value_type & refernce_type
Reference to the buffer elements.
Definition: iffl_common.h:1065
pointer_type last
Pointer to the last element in the list nullptr if no buffer or if there is no elements in the list.
Definition: iffl_common.h:1081
constexpr void set_size(size_type size) noexcept
Updates buffer size.
Definition: iffl_common.h:1116
constexpr void arm() noexcept
Can be used to re-arm guard after prior disarm or discharge.
Definition: iffl_common.h:455
constexpr size_t padding_size() const noexcept
Definition: iffl_common.h:711
buffer_t & operator=(buffer_t const &)=default
Copy assignment operator.
void * cast_to_void_ptr(T *p) noexcept
Helper method to cast a pointer to a void *.
Definition: iffl_common.h:375
Tag type for value - initializing first, constructing second from remaining arguments.
Definition: iffl_common.h:790
Vocabulary type that describes an offset in a larger buffer and template parameter that specifies ele...
Definition: iffl_common.h:693
constexpr size_t offset_aligned() const noexcept
Definition: iffl_common.h:705
constexpr compressed_pair(zero_then_variadic_args_t, P &&... p)
Constructor.
Definition: iffl_common.h:833
constexpr void validate() const noexcept
Fail fast is invariants are broken.
Definition: iffl_common.h:1146
constexpr size_t remaining_capacity_for_insert() const
Definition: iffl_common.h:769
constexpr scope_guard(G const &g)
Constructor from an instance of functor.
Definition: iffl_common.h:405
constexpr size_with_padding< ALIGNMENT_V > used_capacity() const
Capacity used by elements in the buffer.
Definition: iffl_common.h:762
Describes buffer used by container.
Definition: iffl_common.h:750
constexpr size_type size() const noexcept
Definition: iffl_common.h:1101
Vocabulary type that describes an size and template parameter that specifies element's type alignment...
Definition: iffl_common.h:722
constexpr size_t buffer_size() const noexcept
Buffer size.
Definition: iffl_common.h:565
buffer_t(T *begin, T *last, T *end) noexcept
Assignment operator to const buffer from pointers.
Definition: iffl_common.h:1034
#define FFL_CODDING_ERROR_IF_NOT(C)
If expression is false then fail fast with error ENOTRECOVERABLE(127 or 0x7f)
Definition: iffl_common.h:120
constexpr T2 const & get_second() const noexcept
Definition: iffl_common.h:970