# ring-span-lite **Repository Path**: paul3rd/ring-span-lite ## Basic Information - **Project Name**: ring-span-lite - **Description**: ring-span lite - A C++yy-like ring_span type for C++98, C++11 and later in a single-file header-only library - **Primary Language**: C++ - **License**: BSL-1.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-05-25 - **Last Updated**: 2025-08-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ring-span lite: A circular buffer view for C++98 and later [![Language](https://img.shields.io/badge/C%2B%2B-98/11/14/17-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![License](https://img.shields.io/badge/license-BSL-blue.svg)](https://opensource.org/licenses/BSL-1.0) [![Build Status](https://github.com/martinmoene/ring-span-lite/actions/workflows/ci.yml/badge.svg)](https://github.com/martinmoene/ring-span-lite/actions/workflows/ci.yml) [![Version](https://badge.fury.io/gh/martinmoene%2Fring-span-lite.svg)](https://github.com/martinmoene/ring-span-lite/releases) [![download](https://img.shields.io/badge/latest-download-blue.svg)](https://raw.githubusercontent.com/martinmoene/ring-span-lite/master/include/nonstd/ring_span.hpp) [![Conan](https://img.shields.io/badge/on-conan-blue.svg)](https://conan.io/center/ring-span-lite) [![Vcpkg](https://img.shields.io/badge/on-vcpkg-blue.svg)](https://vcpkg.link/ports/ring-span-lite) [![Try it on wandbox](https://img.shields.io/badge/on-wandbox-blue.svg)](https://wandbox.org/permlink/GHo8T1PIo7TV7eoG) [![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/7n4Byc) **Contents** - [Example usage](#example-usage) - [In a nutshell](#in-a-nutshell) - [Dependencies](#dependencies) - [Installation](#installation) - [Synopsis](#synopsis) - [Reported to work with](#reported-to-work-with) - [Building the tests](#building-the-tests) - [Other ring_span implementations](#other-ring-span-implementations) - [Notes and references](#notes-and-references) - [Appendix](#appendix) Example usage ------------- ```Cpp #include "nonstd/ring_span.hpp" #include #include template< typename T, size_t N > inline size_t dim( T (&arr)[N] ) { return N; } template< typename T, class Popper> inline std::ostream & operator<<( std::ostream & os, ::nonstd::ring_span const & rs ) { os << "[ring_span: "; std::copy( rs.begin(), rs.end(), std::ostream_iterator(os, ", ") ); return os << "]"; } int main() { double arr[] = { 2.0 , 3.0, 5.0, }; double coeff[] = { 0.25, 0.5, 0.25 }; nonstd::ring_span buffer( arr, arr + dim(arr), arr, dim(arr) ); std::cout << buffer << "\n"; // new sample: buffer.push_back( 7.0 ); std::cout << buffer << "\n"; double result = std::inner_product( buffer.begin(), buffer.end(), coeff, 0.0 ); std::cout << "filter result: " << result << "\n"; } ``` ### Compile and run ```Text prompt> g++ -std=c++98 -Wall -I../include -o 01-filter.exe 01-filter.cpp && 01-filter.exe [ring_span: 2, 3, 5, ] [ring_span: 3, 5, 7, ] filter result: 5 ``` Or to run with [Buck](https://buckbuild.com/): ```Text prompt> buck run example/:01-filter ``` In a nutshell ------------- **ring-span lite** is a single-file header-only library to represent a circular buffer view on a container. The library aims to provide a [C++yy-like ring_span]() for use with C++98 and later [1][2]. Its initial code is inspired on the reference implementation by Arthur O'Dwyer [3]. It is my intention to let the interface of this `ring_span` follow the unfolding standard one. This library also includes header `` to provide a data-owning ring buffer. **Features and properties of ring-span lite** are ease of installation (single header), freedom of dependencies other than the standard library. **Limitations of ring-span lite** are ... . License ------- *ring-span lite* is distributed under the [Boost Software License](LICENSE.txt). Dependencies ------------ *ring-span lite* has no other dependencies than the [C++ standard library](http://en.cppreference.com/w/cpp/header). Installation ------------ *ring-span lite* is a single-file header-only library. Put `ring_span.hpp` in the [include](include) folder directly into the project source tree or somewhere reachable from your project. Synopsis -------- **Contents** - [Types in namespace nonstd](#types-in-namespace-nonstd) - [Interface of *ring-span lite*](#interface-of-ring-span-lite) - [Non-member functions for *ring-span lite*](#non-member-functions-for-ring-span-lite) - [Configuration macros](#configuration-macros) ### Types in namespace nonstd | Purpose |[p0059](http://wg21.link/p0059)| Type | Notes | |---------|:-----------------------------:|------|-------| | Circular buffer view |✓/–| template<
 class T
 , class Popper = default_popper<T>
 , bool `CapacityIsPowerOf2` = false
>
class **ring_span** | See Note 1 below. | | Ignore element |✓| template< class T >
class **null_popper** |   | | Return element |✓| template< class T >
class **default_popper** |   | | Return element, replace original |✓| template< class T >
class **copy_popper** |   | Note 1: `CapacityIsPowerOf2` is an extension (`nsrs_CONFIG_STRICT_P0059=0`).With `CapacityIsPowerOf2` being `true`, method `normalize_()` is optimized to use bitwise and instead of modulo division. ### Interface of *ring-span lite* #### Class `ring_span` | Kind |[p0059](http://wg21.link/p0059)| Type / Method | Note / Result | |-------|:--------------:|-----------------------------|---------------| | Various types |✓| **type** |ring_span<T, Popper\[, CapacityIsPowerOf2\]> | |   |✓| **size_type** |  | | Value types |✓| **value_type** |  | |   |✓| **pointer** |  | |   |✓| **reference** |  | |   |✓| **const_reference** |  | | Iterator types |✓| **iterator** |  | |   |✓| **const_iterator** |  | |   |– | **reverse_iterator** |  | |   |– | **const_reverse_iterator** |  | | Construction |✓| **ring_span**(
It begin, It end
, Popper popper = Popper() ) noexcept | create empty span of
distance(begin,end) capacity | |   |✓| **ring_span**(
It begin, It end
, It first, size_type size
, Popper popper = Popper() ) noexcept | create partially filled span of
distance(begin,end) capacity,
size elements | |   |✓| **ring_span**( ring_span && ) | = default (>= C++11) | |   |✓| ring_span& **operator=**( ring_span && ) | = default (>= C++11) | |   |✓| **ring_span**( ring_span const & ) | implicitly deleted (>= C++11) | |   |✓| ring_span & **operator=**( ring_span const & ); | implicitly deleted (>= C++11) | |   |– | **ring_span**( ring_span const & ) | declared private (< C++11) | |   |– | ring_span & **operator=**( ring_span const & ); | declared private (< C++11) | | Iteration |✓| **begin**() noexcept | iterator | |   |✓| **begin**() noexcept | const_iterator | |   |✓| **cbegin**() noexcept | const_iterator | |   |✓| **end**() noexcept | iterator | |   |✓| **end**() noexcept | const_iterator | |   |✓| **cend**() noexcept | const_iterator | | Reverse iter. |– | **rbegin**() noexcept | reverse_iterator | |   |– | **rbegin**() noexcept | const_reverse_iterator | |   |– | **crbegin**() noexcept | const_reverse_iterator | |   |– | **rend**() noexcept | reverse_iterator | |   |– | **rend**() noexcept | const_reverse_iterator | |   |– | **crend**() noexcept | const_reverse_iterator | | Observation |✓| **empty**() noexcept | true if empty | |   |✓| **full**() noexcept | true if full | |   |✓| **size**() noexcept | current number of elements | |   |✓| **capacity**() noexcept| maximum number of elements | | Element access |✓| **front**() noexcept | reference to element at front | |   |✓| **front**() noexcept | const_reference to element at front | |   |✓| **back**() noexcept | reference to back element at back | |   |✓| **back**() noexcept | const_reference to element at back | |   |– | **operator[]**( size_type idx ) noexcept | reference to element at specified index | |   |– | **operator[]**( size_type idx ) noexcept | const_reference to element at specified index | | Elem.extraction|✓| **pop_front**() | Popper::return_type (p0059: auto) | |   |– | **pop_back**() | Popper::return_type | | Elem.insertion|✓ | **push_back**( value_type const & value ) noexcept(…) | void; restrained (>= C++11) | |   |– | **push_back**( value_type const & value ) | void; unrestrained (< C++11) | |   |✓| **push_back**( value_type && value ) noexcept(…) | void; restrained (>= C++11) | |   |✓| **emplace_back**( Args &&... args ) noexcept(…)| void; restrained (>= C++11) | |   |– | **push_front**( value_type const & value ) noexcept(…) | void; restrained (>= C++11) | |   |– | **push_front**( value_type const & value ) | void; unrestrained (< C++11) | |   |– | **push_front**( value_type && value ) noexcept(…)| void; restrained (>= C++11) | |   |– | **emplace_front**( Args &&... args ) noexcept(…) | void; restrained (>= C++11) | | Swap |✓| **swap**( ring_span & rhs ) noexcept | void; | #### Class `ring_iterator` | Kind |[p0059](http://wg21.link/p0059)| Type / Method | Note / Result | |-------|:--------------:|------------------------------|---------------| | Various types |✓| **type** |ring_span< T, Popper > | |   |✓| **difference_type** |  | | Value types |✓| **value_type** |  | |   |✓| **pointer** |  | |   |✓| **reference** |  | | Category |✓| **iterator_category** |  | | Construction |✓| **ring_iterator**() | = default (>= C++11) | |   |– | **ring_iterator**() | (< C++11) | | Conversion |– | **operator ring_iterator<…,true>**() const noexcept| const ring_iterator | | Element access|✓| **operator\***() const noexcept |reference | | Increment |✓| **operator++**() noexcept |ring_iterator<…> & | |   |✓| **operator++**( int ) noexcept |ring_iterator<…> | | Decrement |✓| **operator--**() noexcept |ring_iterator<…> & | |   |✓| **operator--**( int ) noexcept |ring_iterator<…> | | Addition |✓| **operator+=**( int i ) noexcept |ring_iterator<…> & | |   |✓| **operator-=**( int i ) noexcept |ring_iterator<…> & | | Difference |– | **operator-**( ring_iterator<…> const & rhs ) | difference_type, Note 1 | | Comparison |✓| **operator==**( ring_iterator<…> const & rhs ) const noexcept |bool, Note 1 | |   |✓| **operator!=**( ring_iterator<…> const & rhs ) const noexcept |bool, Note 1 | |   |✓| **operator<**( ring_iterator<…> const & rhs ) const noexcept |bool, Note 1 | |   |✓| **operator<=**( ring_iterator<…> const & rhs ) const noexcept |bool, Note 1 | |   |✓| **operator>**( ring_iterator<…> const & rhs ) const noexcept |bool, Note 1 | |   |✓| **operator>=**( ring_iterator<…> const & rhs ) const noexcept |bool, Note 1 | Note 1: accepts lhs and rhs of different const-ness. ### Non-member functions for *ring-span lite* | Kind |[p0059](http://wg21.link/p0059)| Function | Note / Result | |-----------------|:-----------------------------:|----------|--------| | Swap |–/✓| **swap**( ring_span<…> & lhs, ring_span<…> & rhs ) |void | | Iterator offset |✓| **operator+**( ring_iterator<…> it, int i ) noexcept | ring_iterator<…> | |   |– | **operator+**( int i, ring_iterator<…> it ) noexcept | ring_iterator<…> | |   |✓| **operator-**( ring_iterator<…> it, int i ) noexcept | ring_iterator<…> | |   |– | **operator-**( int i, ring_iterator<…> it ) noexcept | ring_iterator<…> | Legenda: – not in proposal · ✓ in proposal · –/✓ not in proposal/in sg14 code #### Class `ring` | Kind | Type / Method | Note / Result | |------|---------------|---------------| | Circular buffer | template<
 class Container
 , bool `CapacityIsPowerOf2` = false
>
class **ring** | See Note 1 below. | | Various types | **size_type** |  | | Value types | **value_type** |  | |   | **reference** |  | |   | **const_reference** |  | | Iterator types | **iterator** |  | |   | **const_iterator** |  | |   | **reverse_iterator** |  | |   | **const_reverse_iterator** |  | | Construction | **ring**() | create empty ring,
C-array, `std::array` | |   | **ring**(size_type size) | create empty ring of capacity `size`,
dynamic container | | Iteration | **begin**() noexcept | iterator | |   | **begin**() noexcept | const_iterator | |   | **cbegin**() noexcept | const_iterator | |   | **end**() noexcept | iterator | |   | **end**() noexcept | const_iterator | |   | **cend**() noexcept | const_iterator | | Reverse iter. | **rbegin**() noexcept | reverse_iterator | |   | **rbegin**() noexcept | const_reverse_iterator | |   | **crbegin**() noexcept | const_reverse_iterator | |   | **rend**() noexcept | reverse_iterator | |   | **rend**() noexcept | const_reverse_iterator | |   | **crend**() noexcept | const_reverse_iterator | | Observation | **empty**() noexcept | true if empty | |   | **full**() noexcept | true if full | |   | **size**() noexcept | current number of elements | |   | **capacity**() noexcept | maximum number of elements | | Element access | **front**() noexcept | reference to element at front | |   | **front**() noexcept | const_reference to element at front | |   | **back**() noexcept | reference to back element at back | |   | **back**() noexcept | const_reference to element at back | | Element access | **front**() noexcept | reference to element at front | |   | **front**() noexcept | const_reference to element at front | |   | **back**() noexcept | reference to back element at back | |   | **back**() noexcept | const_reference to element at back | |   | **operator[]**( size_type idx ) noexcept | reference to element at specified index | |   | **operator[]**( size_type idx ) noexcept | const_reference to element at specified index | | Elem.extraction| **pop_front**() | Popper::return_type | |   | **pop_back**() | Popper::return_type | | Elem.insertion|& **push_back**( value_type const & value ) noexcept(…) | void; restrained (>= C++11) | |   | **push_back**( value_type const & value ) | void; unrestrained (< C++11) | |   | **push_back**( value_type && value ) noexcept(…) | void; restrained (>= C++11) | |   | **emplace_back**( Args &&... args ) noexcept(…)| void; restrained (>= C++11) | |   | **push_front**( value_type const & value ) noexcept(…) | void; restrained (>= C++11) | |   | **push_front**( value_type const & value ) | void; unrestrained (< C++11) | |   | **push_front**( value_type && value ) noexcept(…)| void; restrained (>= C++11) | |   | **emplace_front**( Args &&... args ) noexcept(…) | void; restrained (>= C++11) | | Swap | **swap**( ring_span & rhs ) noexcept | void; | Note 1: `CapacityIsPowerOf2` is an extension (`nsrs_CONFIG_STRICT_P0059=0`).With `CapacityIsPowerOf2` being `true`, method `normalize_()` is optimized to use bitwise and instead of modulo division. Class `default_popper` is used as popper. ### Configuration macros #### Tweak header If the compiler supports [`__has_include()`](https://en.cppreference.com/w/cpp/preprocessor/include), *ring-span lite* supports the [tweak header](https://vector-of-bool.github.io/2020/10/04/lib-configuration.html) mechanism. Provide your *tweak header* as `nonstd/ring_span.tweak.hpp` in a folder in the include-search-path. In the tweak header, provide definitions as documented below, like `#define nsrs_CPLUSPLUS 201103L`. #### Standard selection macro \-Dnsrs\_CPLUSPLUS=199711L Define this macro to override the auto-detection of the supported C++ standard, if your compiler does not set the `__cpluplus` macro correctly. #### Select `std::ring_span` or `nonstd::ring_span` At default, *ring_span lite* uses `std::ring_span` if it is available and lets you use it via namespace `nonstd`. You can however override this default and explicitly request to use `std::ring_span` or ring_span lite's `nonstd::ring_span` as `nonstd::ring_span` via the following macros. -Dnsrs\_CONFIG\_SELECT\_RING\_SPAN=nsrs_RING_SPAN_DEFAULT Define this to `nsrs_RING_SPAN_STD` to select `std::ring_span` as `nonstd::ring_span`. Define this to `nsrs_RING_SPAN_NONSTD` to select `nonstd::ring_span` as `nonstd::ring_span`. Default is undefined, which has the same effect as defining to `nsrs_RING_SPAN_DEFAULT`. #### Disable extensions \-Dnsrs\_CONFIG\_STRICT\_P0059=0 Define this to 1 to omit behaviour not present in proposal [p0059](http://wg21.link/p0059). Default is undefined (same effect as 0). #### Enable popper empty base class optimization \-Dnsrs\_CONFIG\_POPPER\_EMPTY\_BASE\_CLASS=0 Poppers are often stateless. To prevent they take up space C++20 attribute `[[no_unique_address]]` is used when available. Another way to prevent up taking space is to make the popper a base class of `class ring_span`. This is what occurs with macro `nsrs_CONFIG_POPPER_EMPTY_BASE_CLASS` defined to 1. This is an extension to proposal p0059. Disabling extensions via macro `nsrs_CONFIG_STRICT_P0059` also disables this extension. Default is undefined (same effect as 0). #### Enable compilation errors \-Dnsrs\_CONFIG\_CONFIRMS\_COMPILATION\_ERRORS=0 Define this to 1 to include the tests with compile-time errors. Default is undefined (same effect as 0). Reported to work with --------------------- The table below mentions the compiler versions *ring-span lite* is reported to work with. OS | Compiler | Versions | ---------:|:-----------|:---------| Windows | Clang/LLVM | ? |   | GCC | 5.2.0, 6.3.0 |   | Visual C++
(Visual Studio)| 8 (2005), 10 (2010), 11 (2012),
12 (2013), 14 (2015, 2017) | GNU/Linux | Clang/LLVM | 3.5.0 |   | GCC | 4.8.4 | OS X | ? | ? | Building the tests ------------------ To build the tests you need: - [Buck](https://buckbuild.com/) or [CMake](http://cmake.org) version 2.8.7 or later to be installed and in your PATH. - A [suitable compiler](#reported-to-work-with). The [*lest* test framework](https://github.com/martinmoene/lest) is included in the [test folder](test). ### Buck To run the tests: ```Text prompt> buck run test/ ``` ### CMake The following steps assume that the [ring-span lite source code](https://github.com/martinmoene/ring-span-lite) has been cloned into a directory named `c:\ring-span-lite`. 1. Create a directory for the build outputs for a particular architecture. Here we use c:\ring-span-lite\build-win-x86-vc10. cd c:\ring-span-lite md build-win-x86-vc10 cd build-win-x86-vc10 2. Configure CMake to use the compiler of your choice (run `cmake --help` for a list). cmake -G "Visual Studio 10 2010" [see 3. below] .. 3. Optional. You can control above configuration through the following options: - `-DRING_SPAN_LITE_COLOURISE_TEST=ON`: use colour for pass, fail, default off 4. Build the test suite in the Debug configuration (alternatively use Release). cmake --build . --config Debug 5. Run the test suite. ctest -V -C Debug All tests should pass, indicating your platform is supported and you are ready to use *ring-span lite*. See the table with [supported types and functions](#features). Other ring-span implementations ------------------------------- - Bjørn Reese. [Circular span](https://github.com/breese/trial.circular). - Jan Wilmans. [ring_span](https://github.com/janwilmans/ring_span), based on code by Björn Fahller. Notes and references -------------------- ### References [1] [p0059: A proposal to add a ring span to the standard library](http://wg21.link/p0059) ([latest](http://wg21.link/p0059), [r4](http://wg21.link/p0059r4), [r3](http://wg21.link/p0059r3), [r2](http://wg21.link/p0059r2), [r1](http://wg21.link/p0059r1), [r0](http://wg21.link/p0059r0)). [2] [WG21-SG14/SG14](https://github.com/WG21-SG14/SG14/). Reference implementation of [`std::ring_span`](https://github.com/WG21-SG14/SG14/blob/master/SG14/ring.h) by [Guy Davidson](https://github.com/hatcat) and [Arthur O'Dwyer](https://github.com/Quuxplusone). [3] [Arthur O'Dwyer](https://github.com/Quuxplusone). Reference implementation of [`std::ring_span`](https://github.com/Quuxplusone/ring_view). [4] Arthur O’Dwyer. [Reference types with metadata cause problems](https://quuxplusone.github.io/blog/2018/05/30/reference-types-with-metadata-cause-problems/). 30 May 2018. [5] Phillip Johnston. [Creating a Circular Buffer in C and C++](https://embeddedartistry.com/blog/2017/4/6/circular-buffers-in-cc). 17 May 2017. [6] Jan Gaspar. [Boost.Circular Buffer](http://www.boost.org/libs/circular_buffer). Appendix -------- **Contents** - [A.1 Applets](#a1) - [A.2 Compile-time information](#a2) - [A.3 Ring-span lite test specification](#a3) ### A.1 Applets Applets demonstrate a specific use case. They are available via tag `[.applet]`. ```Text > ring-span-main.t.exe -l .applet ring_span: filter[.applet] ``` ### A.2 Compile-time information The version of *ring-span lite* is available via tag `[.version]`. The following tags are available for information on the compiler and on the C++ standard library used: `[.compiler]`, `[.stdc++]`, `[.stdlanguage]` and `[.stdlibrary]`. ### A.3 Ring-span lite test specification Note: test cases that assert are tagged with `[.assert]` and only run when [.assert] is included on the command line, like: `test [.assert] partial-test-name`.
click to expand

```Text ring_span: Allows to construct an empty span from an iterator pair ring_span: Allows to construct an empty span from an iterator pair - capacity is power of 2 ring_span: Allows to construct a partially filled span from an iterator pair and iterator, size ring_span: Allows to construct a partially filled span from an iterator pair and iterator, size - capacity is power of 2 ring_span: Disallows to copy-construct from a ring_span (compile-time) ring_span: Disallows to copy-assign from a ring_span (compile-time) ring_span: Allows to move-construct from a ring_span (C++11) ring_span: Allows to move-assign from a ring_span (C++11) ring_span: Allows to obtain the capacity of a span ring_span: Allows to obtain the number of elements in a span (size) ring_span: Allows to check for an empty span ring_span: Allows to check for a full span ring_span: Allows to observe the element at the specified index [extension] ring_span: Allows to observe the element at the front ring_span: Allows to observe the element at the back ring_span: Allows to obtain and remove the element at the front ring_span: Allows to obtain and remove the element at the back [extension] ring_span: Allows to copy-insert an element at the front [extension] ring_span: Allows to move-insert an element at the front (C++11) [extension] ring_span: Allows to emplace an element at the front (C++11) [extension] ring_span: Allows to copy-insert an element at the back ring_span: Allows to move-insert an element at the back (C++11) ring_span: Allows to emplace an element at the back (C++11) ring_span: Adding an element to an empty span makes it non-empty (front) [extension] ring_span: Adding an element to an empty span makes it non-empty (back) ring_span: Adding an element to an empty span doesn't change its capacity (front) [extension] ring_span: Adding an element to an empty span doesn't change its capacity (back) ring_span: Adding an element to a full span leaves it full (front) [extension] ring_span: Adding an element to a full span leaves it full (back) ring_span: Adding an element to a full span doesn't change its capacity (front) [extension] ring_span: Adding an element to a full span doesn't change its capacity (back) ring_span: Removing an element from a span with one element makes it empty (front) ring_span: Removing an element from a span with one element makes it empty (back) [extension] ring_span: Removing an element from a span with one element doesn't change its capacity (front) ring_span: Removing an element from a span with one element doesn't change its capacity (back) [extension] ring_span: Removing an element from a full span makes it not full (front) ring_span: Removing an element from a full span makes it not full (back) [extension] ring_span: Removing an element from a full span doesn't change its capacity (front) ring_span: Removing an element from a full span doesn't change its capacity (back) [extension] ring_span: Allows to swap spans (member) ring_span: Allows to swap spans (non-member) ring_span: Allows to appear in range-for (C++11) ring_span: Allows iteration (non-const) ring_span: Allows iteration (const) ring_span: Allows iteration (mixed const-non-const) ring_span: Allows reverse iteration (non-const) [extension] ring_span: Allows reverse iteration (const) [extension] ring_span: Allows reverse iteration (mixed const-non-const) [extension] ring_span: A span with capacity zero is both empty and full ring_span: A full span is a delay-line of capacity elements (back-front) ring_span: A full span is a delay-line of capacity elements (front-back) [extension] ring_span: A non-full span is a stack of capacity elements (back) [extension] ring_span: A non-full span is a stack of capacity elements (front) [extension] ring_span: A non-full span behaves like an harmonica (back-front) ring_span: A non-full span behaves like an harmonica (front-back) [extension] ring_iterator: Allows conversion to const ring_iterator [extension] ring_iterator: Allows to dereference iterator (operator*()) ring_iterator: Allows to dereference iterator (operator->()) ring_iterator: Allows to index from iterator (operator[](size_t)) ring_iterator: Allows to increment iterator (prefix) ring_iterator: Allows to increment iterator (postfix) ring_iterator: Allows to decrement iterator (prefix) ring_iterator: Allows to decrement iterator (postfix) ring_iterator: Allows to advance iterator (+=) [extension] ring_iterator: Allows to advance iterator (-=) [extension] ring_iterator: Allows to offset iterator (+) [extension] ring_iterator: Allows to offset iterator (-) [extension] ring_iterator: Allows to obtain difference of iterators [extension] ring_iterator: Allows to compare iterators (==) ring_iterator: Allows to compare iterators (!=) ring_iterator: Allows to compare iterators (<) ring_iterator: Allows to compare iterators (<=) ring_iterator: Allows to compare iterators (>) ring_iterator: Allows to compare iterators (>=) ring_iterator: Allows to compare iterators (mixed const-non-const) null_popper: A null popper returns void null_popper: A null popper leaves the original element unchanged default_popper: A default popper returns the element default_popper: A default popper moves the element (C++11) default_popper: A default popper leaves the original element unchanged copy_popper: A copy popper returns the element copy_popper: A copy popper replaces the original element ring: Allows to create data owning ring from container ring: Allows to create data owning ring from container - capacity is power of 2 ring: Allows to create data owning ring from std::array (C++11) ring: Allows to create data owning ring from C-array tweak header: reads tweak header if supported [tweak] ```