ring-span lite - A C++yy-like ring_span type for C++98, C++11 and later in a single-file header-only library

Overview

ring-span lite: A circular buffer view for C++98 and later

Language License Build Status Build status Version download Conan Try it on wandbox Try it on godbolt online

Contents

Example usage

#include "nonstd/ring_span.hpp"
#include <iostream>
#include <numeric>

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<T, Popper> const & rs )
{
    os << "[ring_span: "; std::copy( rs.begin(), rs.end(), std::ostream_iterator<T>(os, ", ") ); return os << "]";
}

int main()
{
    double arr[]   = { 2.0 , 3.0, 5.0, };
    double coeff[] = { 0.25, 0.5, 0.25 };

    nonstd::ring_span<double> 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

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:

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 <ring.hpp> 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.

Dependencies

ring-span lite has no other dependencies than the C++ standard library.

Installation

ring-span lite is a single-file header-only library. Put ring_span.hpp in the include folder directly into the project source tree or somewhere reachable from your project.

Synopsis

Contents

Types in namespace nonstd

Purpose 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 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 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 Function Note / Result
Swap –/✓ swap( ring_span<…> & lhs, ring_span<…> & rhs ) void
Iterator offset operator+( ring_iterator<…> it, int i ) noexcept ring_iterator<…>
  operator-( ring_iterator<…> it, int i ) 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(size_type size) create empty ring of capacity size
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(), ring-span lite supports the tweak header 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. 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:

The lest test framework is included in the test folder.

Buck

To run the tests:

prompt> buck run test/

CMake

The following steps assume that the ring-span lite source code 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.

Other ring-span implementations

Notes and references

References

[1] p0059: A proposal to add a ring span to the standard library (latest, r4, r3, r2, r1, r0).
[2] WG21-SG14/SG14. Reference implementation of std::ring_span by Guy Davidson and Arthur O'Dwyer.
[3] Arthur O'Dwyer. Reference implementation of std::ring_span.
[4] Arthur O’Dwyer. Reference types with metadata cause problems. 30 May 2018.
[5] Phillip Johnston. Creating a Circular Buffer in C and C++. 17 May 2017.
[6] Jan Gaspar. Boost.Circular Buffer.

Appendix

Contents

A.1 Applets

Applets demonstrate a specific use case. They are available via tag [.applet].

> 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

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 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
tweak header: reads tweak header if supported [tweak]

Comments
  • Empty base optimization for m_popper

    Empty base optimization for m_popper

    Right now, popper is a field, m_popper. We store a byte for m_popper even though the popper is usually stateless. If the popper were instead a base class, there would be no size penalty in the case that m_popper has no state.

    opened by dcolascione 5
  • Include a ring container?

    Include a ring container?

    For the sake of encapsulation I’d like to make a container that is a ring buffer and contains the data too.

    As far as I can tell, that would basically be a class that combines a std::array and a ring span, with all of the container functionality handled by the ring span.

    Is there a reason this does not exist?

    opened by peter-moran 5
  • Undefined behavior on partially filled span overflow

    Undefined behavior on partially filled span overflow

    In case of overflow:

    int arr[] = { 0, 1 , 2 };
    ring_span<int> rs( arr, arr + dim(arr), arr + 1, 3 );
    

    https://github.com/martinmoene/ring-span-lite/blob/dfb7c345d6ad856246df162bc891900a74963747/include/nonstd/ring_span.hpp#L432-L445 Should assert(first + size <= end); be added?

    opened by justinboneh 4
  • Attribution

    Attribution

    Source implementation is Guy Davidson and Arthur O'Dwyer, not solely arthur. The initial implementation was by Guy, and he is prrimary force behind the C++ proposal. Also, you might want to take a look at plf::colony for correcting compiler feature detection.

    opened by mattreecebentley 4
  • Add capacity-is-always-power-of-2 mode for normalize_()

    Add capacity-is-always-power-of-2 mode for normalize_()

    ring_span's normalize_() function uses the modulus operator, which emits a division instruction on most architectures. Division is slow: for example, on a Ryzen, division might take 8-13 cycles while add and subtract might take only one or two. Can ring_span gain a template parameter that makes it assume the capacity is power of two and compute normalize_ with masking instead of modulus?

    (Using __builtin_unreachable() doesn't seem sufficient to make the recent GCC or Clang optimize the modulus to masking.)

    opened by dcolascione 3
  • Implement `operator->()` for iterators?

    Implement `operator->()` for iterators?

    Hey there,

    I am not usually a C++ developer, but I was wondering if there was any reason that the -> operator is not implemented.

    I have some code where I need to access some iterators in the context of a more complicated for loop and it would be very convenient.

    It seems that some resources I've read about implementing iterators say to implement it, and some don't mention it.

    opened by Lyle-Alloy 3
  • Compile issue in example

    Compile issue in example

    In example 03-make-ring-span.cpp, if you define PROVIDE_MAKE_RING_SPAN_FROM_GENERIC_CONTAINER

    You will get a compile error.

    At line 156, the end of namespace should come before the #endif

    156: #endif // PROVIDE_MAKE_RING_SPAN_FROM_GENERIC_CONTAINER 157: 158: } // namespace nonstd

    opened by DougRogers 1
  • clear() member function

    clear() member function

    opened by degski 1
  • Make ring_iterator::operator- a member, templated on is_const

    Make ring_iterator::operator- a member, templated on is_const

    template< bool C >
    difference_type operator-( ring_iterator<RS, C> const & rhs) const nsrs_noexcept;
    

    And add:

    friend class ring_iterator<RS, !is_const>;
    
    opened by martinmoene 1
  • Remove Travis CI configuration and badge

    Remove Travis CI configuration and badge

    opened by striezel 0
  • Update actions/checkout in GitHub Actions to v3

    Update actions/checkout in GitHub Actions to v3

    Updates the actions/checkout action used in the GitHub Actions workflow to its newest major version.

    Changes in actions/checkout:

    v3.1.0

    • Use @actions/core saveState and getState
    • Add github-server-url input

    v3.0.2

    • Add input set-safe-directory

    v3.0.1

    • Fixed an issue where checkout failed to run in container jobs due to the new git setting safe.directory
    • Bumped various npm package versions

    v3.0.0

    • Update to node 16

    As far as I can tell this should all be backwards compatible, so I do not expect any breakage.

    Contributes to https://github.com/martinmoene/nonstd-lite-project/issues/70.

    opened by striezel 0
  • Atomic push/pop

    Atomic push/pop

    Are ring-span's push/pop safe for unsynchronized consumer/producer scenarios? Does it even make sense to support such functionality given ring-span's domain (eg by using a policy) or does it make sense to write a wrapper on top of it to provide atomicity? On the top of my head writing a lock-free wrapper on top of ring-span does not seem possible. Modifying ring-span should be more straightforward in comparison. Then again the iterator-based functionality may not be suitable for such usage so maybe this should be out of scope.

    opened by liarokapisv 0
  • Shared memory question?

    Shared memory question?

    Hey, Your project looks promising. Can it work with shared memory? We would like to have a ring buffer between two different processes to share images and metadata

    opened by oak-tree 2
  • Update README's OSX: ??? line

    Update README's OSX: ??? line

    Hi Martin,

    I want to report that I am successfully using ring-span-lite on OSX 10.14 with this clang version:

    clang version 6.0.1 (tags/RELEASE_601/final)
    Target: x86_64-apple-darwin18.0.0
    Thread model: posix
    InstalledDir: /usr/local/opt/llvm/bin
    
    opened by phillipjohnston 0
Releases(v0.6.0)
  • v0.6.0(Jul 18, 2021)

  • v0.5.0(Jul 10, 2021)

    ring_span-lite v0.5.0 adds template parameter flag CapacityIsPowerOf2 and class ring.

    CapacityIsPowerOf2 is an extension (nsrs_CONFIG_STRICT_P0059=0). With CapacityIsPowerOf2 being true, method normalize_() to compute the buffer index is optimized to use bitwise and instead of modulo division.

    class ring is a data-owning ring class. See the discussion on design at issue #20.

    Additions:

    • Add data-owning class ring (#20, thanks to @peter-moran).
    • Add ring_iterator::operator->() (#21, thanks @Lyle-Alloy, @Quuxplusone).
    • Add CapacityIsPowerOf2 template parameter to class ring_span and class ring (#22, thanks @dcolascione).
    • Add script test/tc-cl.bat to compile with clang-cl (nonstd-lite-project issues 54).
    • Add export() to CMakeLists.txt enabling importing targets.
    • Add image Visual Studio 2019 to AppVeyor CI.

    Changes:

    • Handle lest test framework as system include to prevent warnings.
    • Change 'on conan' link to refer to conan center.

    Fixes:

    • none
    Source code(tar.gz)
    Source code(zip)
    ring.hpp(6.45 KB)
    ring_span.hpp(26.56 KB)
  • v0.4.0(Oct 17, 2020)

    [to be expanded]

    This release of ring-span-lite lite ...

    Additions

    Changes

    Fixes


    • [skip ci] Add .editorconfig
    • [skip ci] Add TortoiseGit integration with GitHub issues
    • [skip ci] Add build folder to .gitignore
    • [skip ci] Add IDE folders/files to .gitignore (.vs, .vscode, CodeBlocks)
    • [skip ci] Add 'ring_span' by Jan Wilmans to section 'Other ring-span implementations'
    • [skip ci] Adapt, guided by markdown lint
    • [skip ci] Add 'Circular span' by Bjørn Reese to section 'Other ring-span implementations'
    • Change requires to use a default template argument (nonstd-lite-project 40), Fixes implementation of nsrs_REQUIRES_T(), see https://github.com/martinmoene/nonstd-lite-project/issues/40
    • [skip ci] Improve MSVC version table (nonstd-lite-project issue 38
    • [skip ci] Use #include in code on Godbolt
    • [skip ci] Update test specification in Readme (#18)
    • Add tag [extension] for non nsrs_CONFIG_STRICT_P0059 code
    • Use assert() as statement, not expression (#18, thanks to @Quuxplusone); in PR merge review comment
    • Add operator[] (#18, thanks to @Neargye)
    • add operator[]
    • add test operator[]
    • update readme
    • [skip ci] Add test to Readme, use the term Constructing, #17
    • Add code and test, closes #17, thanks to @justinboneh and @Quuxplusone
    • Add test for #17 (C++98), thanks to @justinboneh and @Quuxplusone
    • Add test for #17, thanks to @justinboneh and @Quuxplusone
    • [skip ci] Add example to clear ring span via assignment (#16)
    • [skip ci] Change vcpkg install to use CMake
    • Improve macro usage consistency (package_config_version)
    • [skip ci] Add settings options to conanfile (thanks to @ngrodzitski) Settings will be removed from package_id after calling self.info.header_only(), but they a helpful for Conan CMake helper to detect generator correctly. https://github.com/martinmoene/nonstd-lite-project/issues/34
    Source code(tar.gz)
    Source code(zip)
    ring_span.hpp(24.86 KB)
  • v0.3.0(May 5, 2019)

  • v0.2.0(Oct 28, 2018)

    Additions

    • Add conversion to const ring_iterator

    Changes

    • class copy_popper now has a single constructor that a) takes its parameter by value if compiled with C++11 or later, or b) takes it parameter by const& otherwise (@Quuxplusone sg14 issue 102).
    • const, noexcept specifiers have been added to popper value access methods.
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(May 13, 2017)

    This release of ring-span lite contains several unrelated changes.

    Additions

    • Buck builds (thanks to Nick La Rooy @njlr )
    • Configuration macro nsrs_CONFIG_STRICT_P0059 to omit ring-span lite extensions
    • CMake option RING_SPAN_LITE_COLOURISE_TEST to control colouring of test output
    • Tests on empty, non-empty, full, non-full spans
    • Tests for mixed const - non-const iterator comparisons
    • Tests that describe delay-line, stack, harmonica behaviour
    • Section in appendix of Readme on compile-time information
    • Table in Readme describing class ring_iterator

    Fixes

    • Fix flags -std=c++11, -std=c++14 for clang in test/CMakeLists.txt
    • Express ring_iterator operator<=() in operator<()
    Source code(tar.gz)
    Source code(zip)
  • v0.0.0(May 9, 2017)

Owner
Martin Moene
C++ programmer at Universiteit Leiden, member and former webeditor of @accu-org.
Martin Moene
Cross-platform STL-styled and STL-compatible library with implementing containers, ranges, iterators, type traits and other tools; actors system; type-safe config interface.

Yato A small repository where I'm gatherting useful snippets and abstractions for C++ development. Yato includes 3 main modules: multidimensional cont

Alexey 10 Dec 18, 2022
C header to execute user-space functions in ring 0

r0e - Execute User Code in Ring0 This small header allows executing functions in your application in ring 0, i.e., with kernel privileges. Use cases i

Michael Schwarz 11 Nov 11, 2022
Strong typedef - A class template that creates a new type that is distinct from the underlying type, but convertible to and from it

jss::strong_typedef <Tag, ValueType, Properties...> This is an implementation of a C++17 class template that provides a wrapper type that is convertib

Anthony Williams 101 Dec 21, 2022
Easy to use, header only, macro generated, generic and type-safe Data Structures in C

C Macro Collections Easy to use, header only, macro generated, generic and type-safe Data Structures in C. Table of Contents Installation Contributing

Leonardo Vencovsky 347 Jan 8, 2023
Step is a C++17, header-only library of STL-like algorithms and data structures

Step is a C++17, header-only library of STL-like algorithms and data structures. Installation git clone --depth 1 https://github.com/storm-ptr/step.gi

storm-ptr 3 Sep 1, 2022
A simple single header 64 and 32 bit hash function using only add, sub, ror, and xor.

K-HASH A simple single header 64 bit hash function using only add, sub, ror, and xor. This a just general-purpose hash function for like making hash m

null 70 Dec 27, 2022
R :package: and header-only C++ library for geospatial space-division based compression and encoding

spress spress provides utilities for encoding and compressing geospatial objects, such as sf objects. Installation This package requires C++11 for com

UF-OKN 5 Dec 9, 2021
R :package: and header-only C++ library for geospatial space-division based compression and encoding

spress spress provides utilities for encoding and compressing geospatial objects, such as sf objects. Installation This package requires C++11 for com

UF-OKN 5 Dec 9, 2021
Library of generic and type safe containers in pure C language (C99 or C11) for a wide collection of container (comparable to the C++ STL).

M*LIB: Generic type-safe Container Library for C language Overview M*LIB (M star lib) is a C library enabling to use generic and type safe container i

PpHd 571 Jan 5, 2023
A library of type safe sets over fixed size collections of types or values, including methods for accessing, modifying, visiting and iterating over those.

cpp_enum_set A library of type safe sets over fixed size collections of types or values, including methods for accessing, modifying, visiting and iter

Carl Dehlin 22 Jun 16, 2022
Generic single-file implementations of AVL tree in C and C++ suitable for deeply embedded systems

Cavl Generic single-file implementation of AVL tree suitable for deeply embedded systems. Simply copy cavl.h or cavl.hpp (depending on which language

Pavel Kirienko 8 Dec 27, 2022
Like neofetch, but much faster because written in c. Only Linux.

fastfetch fastfetch is a neofetch like tool for fetching system information and displaying them in a pretty way. It is written in c to achieve much be

Linus Dierheimer 490 Jan 7, 2023
This is like Inverting Binary Tree, but instead of a Binary Tree it's a File Tree.

Invert File Tree in C++ This is like Inverting Binary Tree, but instead of the Binary Tree it's a File Tree. This is intended as a simple exercise to

Tsoding 12 Nov 23, 2022
nanoplan is a header-only C++11 library for search-based robot planning.

nanoplan is a header-only C++11 library for search-based robot planning. The primary design goals are correctness, ease-of-use, and efficiency (in tha

Jordan Ford 14 May 17, 2022
Miniz in a single C header.

MiniMiniZ This the amalgamated miniz library in a single header. Usage Copy miniminiz.h into your C or C++ project, include it anywhere you want to us

Eduardo Bart 8 Jul 20, 2022
A family of header-only, very fast and memory-friendly hashmap and btree containers.

The Parallel Hashmap Overview This repository aims to provide a set of excellent hash map implementations, as well as a btree alternative to std::map

Gregory Popovitch 1.7k Jan 9, 2023
A realtime/embedded-friendly C++11 variant type which is never empty and prevents undesirable implicit conversions

strict variant Do you use boost::variant or one of the many open-source C++11 implementations of a "tagged union" or variant type in your C++ projects

Chris Beck 90 Oct 10, 2022
BladeBit - Fast Chia (XCH) RAM-only k32-only Plotter

BladeBit Chia Plotter A fast RAM-only, k32-only, Chia plotter. Requirements 416 GiB of RAM are required to run it, plus a few more megabytes for stack

Chia Network 237 Dec 12, 2022
Fixed point 48.16 bit arithmetic type

fixed_math written from scratch fixed point math library in C++17 features minimum c++17 compiler required fixed point 48.16 arithmethic strong type w

Artur Bac 52 Dec 30, 2022