All Projects → martinmoene → Ring Span Lite

martinmoene / Ring Span Lite

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

Programming Languages

cpp11
221 projects
cpp17
186 projects
cpp14
131 projects
ring
36 projects

Projects that are alternatives of or similar to Ring Span Lite

Robin Hood Hashing
Fast & memory efficient hashtable based on robin hood hashing for C++11/14/17/20
Stars: ✭ 658 (+631.11%)
Mutual labels:  no-dependencies
Observer Ptr Lite
observer-ptr - An observer_ptr for C++98 and later in a single-file header-only library (Extensions for Library Fundamentals, v2, v3)
Stars: ✭ 34 (-62.22%)
Mutual labels:  no-dependencies
Physunits Ct Cpp11
A small C++11, C++14 header-only library for compile-time dimensional analysis and unit/quantity manipulation and conversion
Stars: ✭ 67 (-25.56%)
Mutual labels:  no-dependencies
Simplog
A simple logger. No dependencies, no special features, just logging.
Stars: ✭ 17 (-81.11%)
Mutual labels:  no-dependencies
Humblelogging
HumbleLogging is a lightweight C++ logging framework. It aims to be extendible, easy to understand and as fast as possible.
Stars: ✭ 15 (-83.33%)
Mutual labels:  no-dependencies
Nameof
Nameof operator for modern C++, simply obtain the name of a variable, type, function, macro, and enum
Stars: ✭ 1,017 (+1030%)
Mutual labels:  no-dependencies
Vuebar
(🗃️ Archived) Vue 2 directive for custom scrollbar that uses native scroll behavior. Lightweight, performant, customizable and without dependencies. Used successfully in production on https://ggather.com
Stars: ✭ 650 (+622.22%)
Mutual labels:  no-dependencies
Colorjson
Fast Color JSON Marshaller + Pretty Printer for Golang
Stars: ✭ 71 (-21.11%)
Mutual labels:  no-dependencies
Vanilla Emoji Picker
Modern emoji picker. Super light 2kb gzipped, simple and no frameworks 😻
Stars: ✭ 20 (-77.78%)
Mutual labels:  no-dependencies
Alagarr
🦍 Alagarr is a request-response helper library that removes the boilerplate from your Node.js (AWS Lambda) serverless functions and helps make your code portable.
Stars: ✭ 58 (-35.56%)
Mutual labels:  no-dependencies
Hed
vim like hex editor
Stars: ✭ 23 (-74.44%)
Mutual labels:  no-dependencies
Cpp redis
C++11 Lightweight Redis client: async, thread-safe, no dependency, pipelining, multi-platform - NO LONGER MAINTAINED - Please check https://github.com/cpp-redis/cpp_redis
Stars: ✭ 855 (+850%)
Mutual labels:  no-dependencies
Nonstd Lite
Parent of *-lite repositories, a migration path to post-C++11 features for pre-C++11 environments
Stars: ✭ 46 (-48.89%)
Mutual labels:  no-dependencies
Byob
An open-source post-exploitation framework for students, researchers and developers.
Stars: ✭ 6,949 (+7621.11%)
Mutual labels:  no-dependencies
Printf
Tiny, fast, non-dependent and fully loaded printf implementation for embedded systems. Extensive test suite passing.
Stars: ✭ 1,157 (+1185.56%)
Mutual labels:  no-dependencies
Units
a compile-time, header-only, dimensional analysis and unit conversion library built on c++14 with no dependencies.
Stars: ✭ 653 (+625.56%)
Mutual labels:  no-dependencies
X Ray
X-Ray is a script that lets users toggle password visibility in forms.
Stars: ✭ 40 (-55.56%)
Mutual labels:  no-dependencies
Modals
Simple modal dialogue windows
Stars: ✭ 85 (-5.56%)
Mutual labels:  no-dependencies
Drop
A small CSS component that turns browser-native <details> elements into dropdown menus.
Stars: ✭ 69 (-23.33%)
Mutual labels:  no-dependencies
Expected Dark
Expected objects for C++11 and later (and later perhaps C++98 )
Stars: ✭ 55 (-38.89%)
Mutual labels:  no-dependencies

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 >
class ring_span
 
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
 

Interface of ring-span lite

Class ring_span

Kind p0059 Type / Method Note / Result
Various types type ring_span< T, Popper >
  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
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;

Configuration macros

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

ring_span: Allows to construct an empty span from an iterator pair
ring_span: Allows to construct a partially filled span from an iterator pair and iterator, size
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
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].