16 #include <type_traits>
21 #ifndef _PASL_DATA_FIXEDCAPACITYBASE_H_
22 #define _PASL_DATA_FIXEDCAPACITYBASE_H_
26 namespace fixedcapacity {
34 template <
class Item,
int Capacity>
40 void operator()(
Item* items) {
45 std::unique_ptr<Item[], Deleter> items;
69 assert(items != NULL);
75 std::swap(items, other.items);
80 template <
class Item,
int Capacity>
84 mutable Item items[Capacity];
101 tmp_items[i] = items[i];
103 items[i] = other.items[i];
105 other.items[i] = tmp_items[i];
126 template <
class Alloc>
127 void copy(
typename Alloc::pointer destination,
128 typename Alloc::const_pointer source,
129 typename Alloc::size_type num) {
137 if (destination < source || destination >= source+num)
138 std::copy(source, source+num, destination);
140 std::copy_backward(source, source+num, destination+num);
143 template <
class Alloc>
144 void pblit(
typename Alloc::const_pointer t1,
int i1,
145 typename Alloc::pointer t2,
int i2,
147 copy<Alloc>(t2 + i2, t1 + i1, nb);
150 template <
class Alloc>
152 typedef typename Alloc::size_type size_type;
154 for (size_type k = 0; k < nb; k++)
155 alloc.destroy(&t[k + i]);
158 template <
class Alloc>
160 destroy_items<Alloc>(t, 0, nb);
181 template <
class Alloc>
183 typename Alloc::size_type num,
185 copy<Alloc>(t + shift_by, t, num);
193 template <
class Alloc>
194 void pfill(
typename Alloc::pointer first,
195 typename Alloc::pointer last,
196 typename Alloc::const_reference val) {
197 std::fill(first, last, val);
207 template <
class Alloc,
int capacity>
209 typename Alloc::pointer t2,
int i2,
212 if (j1 <= capacity) {
213 pblit<Alloc>(t1, i1, t2, i2, nb);
215 int na = capacity - i1;
216 int i2_n = (i2 + na) % capacity;
217 pblit<Alloc>(t1, i1, t2, i2, na);
218 pblit<Alloc>(t1, 0, t2, i2_n, nb - na);
226 template <
class Alloc,
int capacity>
228 typename Alloc::pointer t2,
int i2,
231 if (j2 <= capacity) {
232 pblit<Alloc>(t1, i1, t2, i2, nb);
234 int na = capacity - i2;
235 int i1_n = (i1 + na) % capacity;
236 pblit<Alloc>(t1, i1, t2, i2, na);
237 pblit<Alloc>(t1, i1_n, t2, 0, nb - na);
246 template <
class Alloc,
int capacity>
248 typename Alloc::pointer t2,
int i2,
251 if (j1 <= capacity) {
252 copy_data_wrap_dst<Alloc, capacity>(t1, i1, t2, i2, nb);
254 int na = capacity - i1;
255 int i2_n = (i2 + na) % capacity;
256 copy_data_wrap_dst<Alloc, capacity>(t1, i1, t2, i2, na);
257 copy_data_wrap_src_and_dst<Alloc, capacity>(t1, 0, t2, i2_n, nb - na);
264 template <
class Alloc,
int capacity>
268 destroy_items<Alloc>(t, i, nb);
270 int na = capacity - i;
271 destroy_items<Alloc>(t, i, na);
272 destroy_items<Alloc>(t, 0, nb - na);
286 template <
class Alloc>
312 template <
class Alloc,
class Body>
323 : body(body), start(start) { }
344 template <
class Body>
345 void papply(
typename Body::allocator_type::pointer t,
346 typename Body::allocator_type::size_type num,
347 typename Body::allocator_type::size_type k,
349 typedef typename Body::allocator_type::size_type size_type;
350 for (size_type i = 0; i < num; i++)
357 template <
class Body>
358 void papply(
typename Body::allocator_type::pointer t,
359 typename Body::allocator_type::size_type num,
360 typename Body::allocator_type::size_type k,
365 pfill<typename Body::allocator_type>(t, t + num, val);
371 template <
class Body,
int capacity>
375 typename Body::allocator_type::size_type k,
379 papply<Body>(t + i, nb, k, body);
381 int na = capacity - i;
382 papply<Body>(t + i, na, k, body);
383 papply<Body>(t, nb - na, na, body);
387 template <
class Body,
int capacity>
392 papply_wrap_dst<Body, capacity>(t, i, nb, 0, body);
414 template <
class Array_alloc,
415 class Item_alloc = std::allocator<typename Array_alloc::value_type> >
424 static constexpr
int capacity = Array_alloc::capacity;
440 : fr(other.fr), sz(other.sz) {
441 copy_data_wrap_src_and_dst<Item_alloc, capacity>(&other.array[0], other.fr, &array[0], fr, other.sz);
474 alloc.construct(&array[fr], x);
483 alloc.construct(&array[bk], x);
491 inline value_type&
back()
const {
493 int bk = fr + sz - 1;
501 value_type v =
front();
502 alloc.destroy(&(
front()));
512 value_type v =
back();
513 alloc.destroy(&(
back()));
565 assert(
size() >= nb);
566 copy_data_wrap_src<Item_alloc, capacity>(&array[0], fr, dst, 0, nb);
569 void backn(value_type* dst,
int nb) {
570 assert(
size() >= nb);
571 int i_new = (fr + sz - nb) % capacity;
572 copy_data_wrap_src<Item_alloc, capacity>(&array[0], i_new, dst, 0, nb);
576 assert(nb +
size() <= capacity);
577 int fr_new = (fr - nb +
capacity) % capacity;
578 copy_data_wrap_dst<Item_alloc, capacity>(xs, 0, &array[0], fr_new, nb);
584 assert(nb +
size() <= capacity);
585 int i = (fr + sz) % capacity;
586 copy_data_wrap_dst<Item_alloc, capacity>(xs, 0, &array[0], i, nb);
591 assert(
size() >= nb);
592 destroy_items_wrap_target<Item_alloc, capacity>(&array[0], fr, nb);
593 fr = (fr + nb) % capacity;
597 template <
class Body>
599 assert(nb +
size() <= capacity);
600 int i = (fr + sz) % capacity;
601 papply_wrap_dst<Body, capacity>(&array[0], i, nb, body);
606 assert(
size() >= nb);
607 int i_new = (fr + sz - nb) % capacity;
608 destroy_items_wrap_target<Item_alloc, capacity>(&array[0], i_new, nb);
623 int i1 = (fr + sz - nb) % capacity;
624 int i2 = (target.fr - nb +
capacity) % capacity;
625 copy_data_wrap_src_and_dst<Item_alloc, capacity>(&array[0], i1, &target.array[0], i2, nb);
633 int i2 = (target.fr + target.sz) % capacity;
634 copy_data_wrap_src_and_dst<Item_alloc, capacity>(&array[0], i1, &target.array[0], i2, nb);
637 fr = (i1 + nb) % capacity;
642 static value_type& subscript(value_type* array,
int fr,
int sz,
int ix) {
643 assert(array != NULL);
646 return array[(fr + ix) % capacity];
652 return subscript(&array[0], fr,
size(), ix);
656 return subscript(&array[0], fr,
size(), (
int)ix);
664 std::swap(fr, other.fr);
665 std::swap(sz, other.sz);
666 array.swap(other.array);
672 value_type* p = subscript(&array[0], fr,
size(), i);
673 value_type* fr_ptr = &
front();
674 value_type& bk_ptr = &
back();
679 assert(p >= &array[0]);
680 assert(p <= &array[capacity-1]);
681 value_type* first = &array[fr];
683 int nb1 = capacity - fr;
684 int nb2 = (int)(p - &array[0]);
687 return (
int)(p - first);
691 template <
class Body>
694 if (bk <= capacity) {
695 for (
int i = fr; i < bk; i++)
700 for (
int i = 0; i < (bk -
capacity); i++)
705 template <
class Body>
707 if (hi - lo <= 0 || hi < 1)
745 template <
class Array_alloc,
746 class Item_alloc = std::allocator<typename Array_alloc::value_type> >
751 static constexpr
int capacity = Array_alloc::capacity - 1;
766 static constexpr
int nb_cells = Array_alloc::capacity;
769 inline value_type* beg()
const {
774 inline value_type* end()
const {
775 return &array[nb_cells-1];
778 inline void check()
const {
790 inline value_type* next(value_type* p)
const {
797 inline value_type* nextn(value_type* p,
int nb)
const {
798 assert(0 <= nb && nb <= nb_cells);
799 value_type* q = p + nb;
806 inline value_type* prev(value_type* p)
const {
813 inline value_type* prevn(value_type* p,
int nb)
const {
814 assert(0 <= nb && nb <= nb_cells);
815 value_type* q = p - nb;
823 inline int array_index_of_pointer(
const value_type* p)
const {
826 int ix = (int) (p - beg());
828 assert (ix < nb_cells);
845 int other_sz = other.
size();
848 int other_ix = other.array_index_of_pointer(other.fr);
849 int ix = array_index_of_pointer(fr);
850 copy_data_wrap_src_and_dst<allocator_type, nb_cells>(other.beg(), other_ix, beg(), ix, other_sz);
851 bk = nextn(bk, other_sz);
869 assert(0 <= i && i <
size());
882 assert(i < nb_cells);
888 int nb = int(bk - fr) + 1;
898 return (bk + 2 == fr) || (bk + 2 - nb_cells == fr);
906 return (bk + 1 == fr) || (bk + 1 - nb_cells == fr);
923 inline value_type&
back()
const {
931 alloc.construct(fr, x);
937 alloc.construct(bk, x);
956 void frontn(value_type* dst,
int nb)
const {
957 assert(0 <= nb && nb <=
size());
958 int ix = array_index_of_pointer(fr);
959 copy_data_wrap_src<Item_alloc, nb_cells>(beg(), ix, dst, 0, nb);
962 void backn(value_type* dst,
int nb)
const {
963 assert(0 <= nb && nb <=
size());
966 value_type* p_start = prevn(bk, nb-1);
967 int ix = array_index_of_pointer(p_start);
968 copy_data_wrap_src<Item_alloc, nb_cells>(beg(), ix, dst, 0, nb);
972 assert(0 <= nb && nb +
size() <= capacity);
974 int ix = array_index_of_pointer(fr);
975 copy_data_wrap_dst<Item_alloc, nb_cells>(src, 0, beg(), ix, nb);
979 assert(0 <= nb && nb +
size() <= capacity);
980 int ix = array_index_of_pointer(next(bk));
981 copy_data_wrap_dst<Item_alloc, nb_cells>(src, 0, beg(), ix, nb);
986 template <
class Body>
988 assert(0 <= nb && nb +
size() <= capacity);
989 int ix = array_index_of_pointer(next(bk));
990 papply_wrap_dst<Body, nb_cells>(beg(), ix, nb, body);
995 assert(0 <= nb && nb <=
size());
996 int ix = array_index_of_pointer(fr);
997 destroy_items_wrap_target<Item_alloc, nb_cells>(beg(), ix, nb);
1002 assert(0 <= nb && nb <=
size());
1004 int ix = array_index_of_pointer(next(bk));
1005 destroy_items_wrap_target<Item_alloc, nb_cells>(beg(), ix, nb);
1019 assert(0 <= nb && nb <=
size());
1021 target.fr = target.prevn(target.fr, nb);
1022 int i1 = array_index_of_pointer(next(bk));
1023 int i2 = target.array_index_of_pointer(target.fr);
1024 copy_data_wrap_src_and_dst<Item_alloc, nb_cells>(beg(), i1, target.beg(), i2, nb);
1030 assert(0 <= nb && nb <=
size());
1031 int i1 = array_index_of_pointer(fr);
1032 int i2 = target.array_index_of_pointer(target.next(target.bk));
1033 copy_data_wrap_src_and_dst<Item_alloc, nb_cells>(beg(), i1, target.beg(), i2, nb);
1035 target.bk = target.nextn(target.bk, nb);
1045 return (*
this)[int(i)];
1053 std::swap(fr, other.fr);
1054 std::swap(bk, other.bk);
1055 array.swap(other.array);
1066 template <
class Body>
1069 int ix = array_index_of_pointer(fr);
1071 papply_wrap_dst<typeof(_body), nb_cells>(beg(), ix, sz, 0, _body);
1075 template <
class Body>
1092 if (hi - lo <= 0 || hi < 1)
1130 template <
class Array_alloc,
1131 class Item_alloc = std::allocator<typename Array_alloc::value_type> >
1136 static constexpr
int capacity = Array_alloc::capacity - 1;
1142 static constexpr
int nbcells = Array_alloc::capacity;
1150 inline value_type* beg()
const {
1155 inline value_type* end()
const {
1156 return &array[nbcells-1];
1159 void check(value_type* fr, value_type* bk)
const {
1160 assert(bk >= beg());
1161 assert(fr >= beg());
1162 assert(bk <= end());
1163 assert(fr <= end());
1167 fr = &array[nbcells-1];
1172 int array_index_of_front(value_type* fr)
const {
1173 return array_index_of_pointer(addr_of_front(fr));
1176 int array_index_of_back(value_type* bk)
const {
1177 return array_index_of_pointer(addr_of_back(bk));
1180 int array_index_of_pointer(
const value_type* p)
const {
1183 return (
int)(p - beg());
1186 value_type* addr_of_front(value_type* fr)
const {
1195 value_type* addr_of_back(value_type* bk)
const {
1204 inline value_type* alloc_front(value_type* fr) {
1214 inline value_type* alloc_back(value_type* bk)
const {
1224 inline value_type* dealloc_front(value_type* fr)
const {
1234 inline value_type* dealloc_back(value_type* bk) {
1244 inline value_type* allocn_front(value_type* fr,
int nb)
const {
1245 assert(nb +
size() <= capacity);
1247 value_type* new_fr = fr - nb;
1249 new_fr = end() - (beg() - new_fr - 1);
1254 inline value_type* allocn_back(value_type* bk,
int nb)
const {
1255 assert(nb +
size() <= capacity);
1257 value_type* new_bk = bk + nb;
1259 new_bk = beg() + (new_bk - end() - 1);
1264 inline value_type* deallocn_front(value_type* fr,
int nb)
const {
1265 assert(
size() >= nb);
1267 value_type* new_fr = fr + nb;
1269 new_fr = beg() + (new_fr - end() - 1);
1274 inline value_type* deallocn_back(value_type* bk,
int nb)
const {
1275 assert(
size() >= nb);
1277 value_type* new_bk = bk - nb;
1279 new_bk = end() - (beg() - new_bk - 1);
1295 #define DEBUG_RINGBUFFER 0
1299 int sz = other.
size();
1300 int other_ix = other.array_index_of_front(other.fr);
1301 #if DEBUG_RINGBUFFER==0
1302 int ix = array_index_of_front(fr);
1303 bk = allocn_back(bk, sz);
1305 fr = beg() + other.array_index_of_pointer(other.fr);
1306 bk = beg() + other.array_index_of_pointer(other.bk);
1307 int ix = array_index_of_front(fr);
1309 copy_data_wrap_src_and_dst<allocator_type, nbcells>(other.beg(), other_ix, beg(), ix, sz);
1327 return int(bk-fr)-1;
1329 return int(bk-(fr-nbcells))-1;
1337 return (bk-fr == 1) || (bk-(fr-nbcells) == 1);
1342 alloc.construct(fr, x);
1343 fr = alloc_front(fr);
1348 alloc.construct(bk, x);
1349 bk = alloc_back(bk);
1354 return *addr_of_front(fr);
1359 return *addr_of_back(bk);
1364 fr = dealloc_front(fr);
1372 bk = dealloc_back(bk);
1379 assert(
size() >= nb);
1380 int ix_fr = array_index_of_front(fr);
1381 copy_data_wrap_src<Item_alloc, nbcells>(beg(), ix_fr, dst, 0, nb);
1384 void backn(value_type* dst,
int nb)
const {
1385 assert(
size() >= nb);
1386 value_type* new_bk = deallocn_back(bk, nb);
1387 int ix_bk = array_index_of_pointer(new_bk);
1388 copy_data_wrap_src<Item_alloc, nbcells>(beg(), ix_bk, dst, 0, nb);
1392 assert(nb +
size() <= capacity);
1393 fr = allocn_front(fr, nb);
1394 int ix_fr = array_index_of_front(fr);
1395 copy_data_wrap_dst<Item_alloc, nbcells>(xs, 0, beg(), ix_fr, nb);
1399 assert(nb +
size() <= capacity);
1400 int ix_bk = array_index_of_pointer(bk);
1401 copy_data_wrap_dst<Item_alloc, nbcells>(xs, 0, beg(), ix_bk, nb);
1402 bk = allocn_back(bk, nb);
1406 assert(
size() >= nb);
1407 int ix_fr = array_index_of_front(fr);
1408 destroy_items_wrap_target<Item_alloc, nbcells>(beg(), ix_fr, nb);
1409 fr = deallocn_front(fr, nb);
1412 template <
class Body>
1414 assert(nb +
size() <= capacity);
1415 int ix_bk = array_index_of_pointer(bk);
1416 papply_wrap_dst<Body, nbcells>(beg(), ix_bk, nb, body);
1417 bk = allocn_back(bk, nb);
1421 assert(
size() >= nb);
1422 bk = deallocn_back(bk, nb);
1423 int ix_bk = array_index_of_pointer(bk);
1424 destroy_items_wrap_target<Item_alloc, nbcells>(beg(), ix_bk, nb);
1438 bk = deallocn_back(bk, nb);
1439 target.fr = target.allocn_front(target.fr, nb);
1440 int i1 = array_index_of_pointer(bk);
1441 int i2 = target.array_index_of_front(target.fr);
1442 copy_data_wrap_src_and_dst<Item_alloc, nbcells>(beg(), i1, target.beg(), i2, nb);
1444 target.check(target.fr, target.bk);
1448 int i1 = array_index_of_front(fr);
1449 int i2 = target.array_index_of_pointer(target.bk);
1450 copy_data_wrap_src_and_dst<Item_alloc, nbcells>(beg(), i1, target.beg(), i2, nb);
1451 fr = deallocn_front(fr, nb);
1452 target.bk = target.allocn_back(target.bk, nb);
1454 target.check(target.fr, target.bk);
1462 return (*
this)[int(ix)];
1470 std::swap(fr, other.fr);
1471 std::swap(bk, other.bk);
1472 array.swap(other.array);
1476 value_type* on_front_item = addr_of_front(fr);
1477 value_type* proj_addr_of_ix = on_front_item + ix;
1478 int array_index_of_ix =
1479 (proj_addr_of_ix <= end())
1480 ?
int(proj_addr_of_ix - beg())
1481 : ix -
int(end() - fr);
1482 return array_index_of_ix;
1487 assert(ix <
size());
1489 value_type* on_fr = addr_of_front(fr);
1490 value_type* on_bk = addr_of_back(bk);
1497 value_type* on_front_item = addr_of_front(fr);
1499 if (p >= on_front_item) {
1500 ix = int(p - on_front_item);
1502 int ix1 = int(end() - fr);
1503 int ix2 = int(p - beg());
1511 template <
class Body>
1524 int ix_fr = array_index_of_front(fr);
1526 papply_wrap_dst<typeof(_body), nbcells>(beg(), ix_fr, sz, 0, _body);
1529 template <
class Body>
1543 if (hi - lo <= 0 || hi < 1)
1579 template <
class Array_alloc,
1580 class Item_alloc = std::allocator<typename Array_alloc::value_type> >
1589 static constexpr
int capacity = Array_alloc::capacity;
1598 assert(array != NULL);
1611 if (other.
size() == 0)
1613 const value_type* ptr = &other[0];
1643 pshiftn<Item_alloc>(&array[0],
size(), +1);
1644 alloc.construct(&array[0], x);
1651 alloc.construct(&array[bk], x);
1666 value_type v =
front();
1667 alloc.destroy(&(
front()));
1668 pshiftn<Item_alloc>(&array.operator[](1),
size() - 1, -1);
1675 value_type v =
back();
1676 alloc.destroy(&(
back()));
1682 assert(
size() >= nb);
1683 copy<Item_alloc>(dst, &array[0], nb);
1687 assert(
size() >= nb);
1688 copy<Item_alloc>(dst, &array.operator[](
size() - nb), nb);
1692 assert(nb +
size() <= capacity);
1693 pshiftn<Item_alloc>(&array[0],
size(), +nb);
1694 copy<Item_alloc>(&array[0], xs, nb);
1699 assert(nb +
size() <= capacity);
1700 copy<Item_alloc>(&array.operator[](
size()), xs, nb);
1704 template <
class Body>
1706 assert(nb +
size() <= capacity);
1707 papply<Body>(&array[bk+1], nb, 0, body);
1712 assert(
size() >= nb);
1713 destroy_items<Item_alloc>(&array[0], nb);
1714 pshiftn<Item_alloc>(&array.operator[](nb),
size() - nb, -nb);
1719 assert(
size() >= nb);
1720 destroy_items<Item_alloc>(&array[0],
size() - nb, nb);
1735 assert(nb <=
size());
1737 pshiftn<Item_alloc>(&target.array[0], target.
size(), +nb);
1743 assert(nb <=
size());
1750 return subscript(&array[0], bk, ix);
1754 return subscript(&array[0], bk, (
size_type)ix);
1762 array.swap(other.array);
1763 std::swap(bk, other.bk);
1768 return (sz > 0) ? sz - 1 : sz;
1773 seg.
begin = &array[0];
1780 assert(p >= &array[0]);
1785 template <
class Body>
1791 template <
class Body>
value_type & operator[](size_t ix) const
void pshiftn(typename Alloc::pointer t, typename Alloc::size_type num, int shift_by)
Polymorphic shift by position.
size_type index_of_last_item() const
void frontn(value_type *dst, int nb) const
static constexpr int capacity
void transfer_from_back_to_front(ringbuffer_idx &target, int nb)
Item_alloc allocator_type
void swap(ringbuffer_ptrx &other)
void popn_front(size_type nb)
Item_alloc allocator_type
void frontn(value_type *dst, int nb)
void popn_front(value_type *dst, int nb)
value_type & operator[](size_type ix) const
ringbuffer_idx(size_type nb, const value_type &val)
value_type * pointer_of_index(int i) const
value_type & operator[](int ix) const
void papply(typename Body::allocator_type::pointer t, typename Body::allocator_type::size_type num, typename Body::allocator_type::size_type k, const Body &body)
Polymorphic apply-to-each item.
segment_type segment_by_index(int ix) const
Fixed-capacity ring buffer.
Fixed-capacity ring buffer.
ringbuffer_ptr(const ringbuffer_ptr &other)
int index_of_pointer(const value_type *p) const
void popn_back(value_type *dst, int nb)
void for_each_segment(size_type lo, size_type hi, const Body &body) const
void for_each(const Body &body) const
segment< value_type * > segment_type
segment< Pointer > segment_of_ringbuffer(Pointer p, Pointer fr, Pointer bk, Pointer a, int capacity)
[segment]
void push_back(const value_type &x)
Loop body for array-initialization by constant.
Array_alloc::value_type value_type
stack(size_type nb, const value_type &val)
void backn(value_type *dst, size_type nb)
void for_each_segment(int lo, int hi, const Body &body) const
void copy_data_wrap_src_and_dst(typename Alloc::const_pointer t1, int i1, typename Alloc::pointer t2, int i2, int nb)
value_type & operator[](int ix) const
segment_type segment_by_index(int i) const
void transfer_from_front_to_back(ringbuffer_idx &target, int nb)
heap_allocator< Item, Capacity > self_type
void pushn_front(const value_type *xs, int nb)
void popn_back(size_type nb)
void destroy_items(typename Alloc::pointer t, int i, int nb)
value_type & front() const
Array_alloc::value_type value_type
ringbuffer_ptr(size_type nb, const value_type &val)
void swap(inline_allocator &other)
Alloc::size_type size_type
value_type & operator[](size_t ix) const
segment< value_type * > segment_type
Item_alloc allocator_type
void pushn_back(const Body &body, int nb)
ringbuffer_ptrx(size_type nb, const value_type &val)
segment_type segment_by_index(size_type ix) const
void push_front(const value_type &x)
void transfer_from_front_to_back(ringbuffer_ptr &target, int nb)
size_type index_of_pointer(const value_type *p) const
void popn_back(value_type *dst, int nb)
void popn_front(value_type *dst, int nb)
void swap(heap_allocator &other)
static constexpr int capacity
void copy(typename Alloc::pointer destination, typename Alloc::const_pointer source, typename Alloc::size_type num)
Polymorphic array copy.
value_type & front() const
void push_front(const value_type &x)
void papply_wrap_dst(typename Body::allocator_type::pointer t, int i, int nb, typename Body::allocator_type::size_type k, const Body &body)
void swap(ringbuffer_idx &other)
Alloc::reference reference
value_type & back() const
segment_type segment_by_index(int i) const
apply_foreach_body(const Body &body, size_type start=0)
void pushn_back(const Body &body, size_type nb)
void push_back(const value_type &x)
void pushn_back(const Body &body, int nb)
value_type & back() const
ringbuffer_idx(const ringbuffer_idx &other)
stack(const stack &other)
Alloc::size_type size_type
int array_index_of_logical_index(int ix) const
void popn_back(value_type *dst, int nb)
void pushn_back(const Body &body, int nb)
ringbuffer_ptrx self_type
static constexpr int capacity
void frontn(value_type *dst, size_type nb)
void copy_data_wrap_src(typename Alloc::const_pointer t1, int i1, typename Alloc::pointer t2, int i2, int nb)
void push_front(const value_type &x)
void pushn_back(const value_type *xs, size_type nb)
void frontn(value_type *dst, int nb) const
void push_back(const value_type &x)
void pushn_back(const value_type *xs, int nb)
void transfer_from_back_to_front(stack &target, size_type nb)
void pushn_front(const value_type *xs, int nb)
void push_front(const value_type &x)
int index_of_pointer(const value_type *p) const
void pushn_front(const value_type *xs, size_type nb)
void popn_front(value_type *dst, size_type nb)
value_type & operator[](int n) const
void for_each(const Body &body) const
Alloc::value_type value_type
void popn_back(value_type *dst, size_type nb)
Alloc::const_reference const_reference
value_type & operator[](size_t i) const
ringbuffer_ptrx(const ringbuffer_ptrx &other)
void pushn_front(const value_type *src, int nb)
Alloc::reference reference
void operator()(size_type i, reference dst) const
value_type & front() const
void for_each(const Body &body) const
static constexpr int capacity
void transfer_from_front_to_back(ringbuffer_ptrx &target, int nb)
void transfer_from_back_to_front(ringbuffer_ptrx &target, int nb)
void destroy_items_wrap_target(typename Alloc::pointer t, int i, int nb)
void pfill(typename Alloc::pointer first, typename Alloc::pointer last, typename Alloc::const_reference val)
Polymorphic fill range with value.
value_type & operator[](int i) const
Array_alloc::value_type value_type
void for_each_segment(int lo, int hi, const Body &body)
void pblit(typename Alloc::const_pointer t1, int i1, typename Alloc::pointer t2, int i2, int nb)
segment< value_type * > segment_type
void pushn_back(const value_type *xs, int nb)
void backn(value_type *dst, int nb) const
void backn(value_type *dst, int nb)
Item_alloc allocator_type
const_foreach_body(const_reference v)
void backn(value_type *dst, int nb) const
void swap(ringbuffer_ptr &other)
value_type & back() const
Loop body for array tabulation.
Fixed-capacity ring buffer, using indices.
value_type & operator[](int i) const
void operator()(size_type i, reference dst) const
value_type & front() const
void transfer_from_back_to_front(ringbuffer_ptr &target, int nb)
void for_each(const Body &body) const
void copy_data_wrap_dst(typename Alloc::const_pointer t1, int i1, typename Alloc::pointer t2, int i2, int nb)
static constexpr int capacity
void for_each_segment(int lo, int hi, const Body &body) const
int index_of_pointer(const value_type *p) const
void transfer_from_front_to_back(stack &target, size_type nb)
value_type & back() const
void pushn_back(const value_type *src, int nb)
void popn_front(value_type *dst, int nb)
void push_back(const value_type &x)
value_type & operator[](size_t ix) const