Simple C++ Algorithms
Classes | Functions
sca Namespace Reference

Classes

class  slice_of
 the underlying type returned by slice() representing a subset of a container More...
 
class  const_slice_of
 const variation of slice_of More...
 

Functions

template<typename C >
size_t size (C &&c)
 return an iterable container's size, regardless if it implements a size() method More...
 
template<typename C >
auto pointers (C &c)
 copy the addresses of elements in a container to a new container More...
 
template<typename C >
auto pointers (const C &c)
 
template<typename C >
auto values (C &&c)
 return a container of deep value copies (never pointers) from a container of values or pointers More...
 
template<typename C >
auto slice (C &&c, size_t idx, size_t len)
 create a slice_of object from a container which allows iteration over a subset of another container More...
 
template<typename C >
auto slice (const C &c, size_t idx, size_t len)
 create a const_slice_of object from a container which allows iteration over a subset of another container More...
 
template<typename C >
auto slice (C &c, size_t idx, size_t len)
 create a const_slice_of object from a container which allows iteration over a subset of another container More...
 
template<typename C >
auto mslice (C &&c, size_t idx, size_t len)
 create a mutable slice_of object which allows iteration of a subset of another container More...
 
template<typename C >
auto mslice (C &c, size_t idx, size_t len)
 
template<typename C , typename C2 , typename... Cs>
auto group (C &&c, C2 &&c2, Cs &&... cs)
 assemble a container containing all elements of two or more containers More...
 
template<typename C >
auto reverse (C &&c)
 return a container where the order of elements is the reverse of the input container More...
 
template<typename C , typename F >
auto sort (C &&c, F &&cmp)
 return a container whose elements are sorted based on a comparison Callable More...
 
template<typename F , typename C >
auto filter (F &&f, C &&c)
 return a filtered container of elements More...
 
template<typename F , typename C , typename... Cs>
auto map (F &&f, C &&c, Cs &&... cs)
 evaluate function with the elements of containers grouped by index and return a container filled with the results of each function call More...
 
template<typename F , typename Result , typename C , typename... Cs>
auto fold (F &&f, Result &&init, C &&c, Cs &&... cs)
 perform a calculation on the elements of containers grouped by index More...
 
template<typename F , typename C , typename... Cs>
void each (F &&f, C &&c, Cs &&... cs)
 evaluate function with the elements of containers grouped by index More...
 
template<typename F , typename C , typename... Cs>
bool all (F &&f, C &&c, Cs &&... cs)
 evaluate if a function returns true with all the elements of containers grouped by index More...
 
template<typename F , typename C , typename... Cs>
bool some (F &&f, C &&c, Cs &&... cs)
 evaluate if a function returns true with at least one of the elements of containers grouped by index More...
 

Detailed Description

A NOTE ON API DESIGN

As a note, much of the complexity of these templates is caused by more effort being put into usability, rather than implementing minimalist algorithms.

The algorithms defined in the c++ standard library typically deal with iterators rather than containers. Instead, this library's data processing algorithms accept iterable objects/containers as arguments and return iterable containers. This leaves the smallest amount of work for the user and reduces risk of exception throwing bugs. This also helps the user avoid making trivial efficiency mistakes when writing algorithm code.

In c++, vectors typically outperform other container types, so algorithms in this library convert to them internally and return them as the result.

PROVIDED ALGORITHMS

The algorithms in this header library are intended for general usecases and composability (the results of one algorithm can often be used as an argument in another). They are not exhaustive, but should cover the majority of simple data processing usecases.

Algorithms and Objects provided by this header:

Function Documentation

◆ all()

template<typename F , typename C , typename... Cs>
bool sca::all ( F &&  f,
C &&  c,
Cs &&...  cs 
)

evaluate if a function returns true with all the elements of containers grouped by index

Evaluation ends when traversible element in container c has been iterated.

Each container can contain a different value type as long as the value type can be passed to the function.

Parameters
fa predicate function applied to elements of input containers
cthe first container whose elements will have f applied to
csthe optional remaining containers whose elements will have f applied to
Returns
true if f returns true for all iterated elements, else false

◆ each()

template<typename F , typename C , typename... Cs>
void sca::each ( F &&  f,
C &&  c,
Cs &&...  cs 
)

evaluate function with the elements of containers grouped by index

Evaluation ends when traversible element in container c has been iterated.

No value is returned from this function, any changes are side effects of executing the function.

Each container can contain a different value type as long as the value type can be passed to the function.

Parameters
fa function to call
cthe first container
cs...the remaining containers

◆ filter()

template<typename F , typename C >
auto sca::filter ( F &&  f,
C &&  c 
)

return a filtered container of elements

Parameters
fa predicate function which gets applied to each element of the input container
cthe input container
Returns
a container of only the elements for which applying the predicate returned true

◆ fold()

template<typename F , typename Result , typename C , typename... Cs>
auto sca::fold ( F &&  f,
Result &&  init,
C &&  c,
Cs &&...  cs 
)

perform a calculation on the elements of containers grouped by index

Evaluation ends when every traversible element in container c has been iterated.

The argument function must accept the current calculated value as its first argument, and the elements of the argument containers stored in the current iteration. The value returned by the function becomes the new current calculated value, which be subsequently passed as an argument to the calculation function in the next iteration. When iteration completes fold() will return the final return value of the calculation function.

Each container can contain a different value type as long as the value type can be passed to the calculation function.

Parameters
fthe calculation function
initthe initial value of the calculation being performed
cthe first container whose elements will be calculated
csoptional additional containers whose elements will also be calculated
Returns
the final calculated value returned from function f

◆ group()

template<typename C , typename C2 , typename... Cs>
auto sca::group ( C &&  c,
C2 &&  c2,
Cs &&...  cs 
)

assemble a container containing all elements of two or more containers

Parameters
cthe first container whose elements should be grouped together with the others
c2the second container whose elements should be grouped together with the others
csoptional, additional containers whose elements should be grouped together with the others
Returns
a container containing all elements of the arguments

◆ map()

template<typename F , typename C , typename... Cs>
auto sca::map ( F &&  f,
C &&  c,
Cs &&...  cs 
)

evaluate function with the elements of containers grouped by index and return a container filled with the results of each function call

Evaluation begins at index 0, and ends when every traversible element in container c has been iterated. It returns an std::vector<T> (where T is the deduced return value of user function f) containing the result of every invocation of user function f.

Each container can contain a different value type as long as the value type can be passed to the function.

Parameters
fa function to call
cthe first container
cs...the remaining containers
Returns
a container R of the results from calling f with elements in c and cs...

◆ mslice()

template<typename C >
auto sca::mslice ( C &&  c,
size_t  idx,
size_t  len 
)

create a mutable slice_of object which allows iteration of a subset of another container

This is the mutable reference implementation of the algorithm, returning a slice_of. This can be dangerous when used inline carelessly, as it will be treated as an rvalue by algorithms causing unexpected swaps. Best usage is to explicitly save the result of this method as an lvalue before usage:

auto my_lvalue_slice = sca::mslice(my_container, 0, 13);
auto my_result = sca::map(my_function, my_lvalue_slice));
auto map(F &&f, C &&c, Cs &&... cs)
evaluate function with the elements of containers grouped by index and return a container filled with...
Definition: scalgorithm.hpp:670
auto mslice(C &&c, size_t idx, size_t len)
create a mutable slice_of object which allows iteration of a subset of another container
Definition: scalgorithm.hpp:558
Parameters
idxstarting index of the range of values
lenlength of range represented by slice
ccontainer to take slice of
Returns
a slice object capable of iterating a given container

◆ pointers()

template<typename C >
auto sca::pointers ( C &  c)

copy the addresses of elements in a container to a new container

This a helper mechanism for ensuring all calculations on data are by reference to a specific set of values. This can be used to simplify operations on large sets of data so that downstream calculations like filter() and map() never have to consider reference value categories.

This algorithm also useful when sorting data in-place without modifying the source data's container positions (std::sort()), while still being able to reference the original data within the sorted set. Furthermore, any kind of sort operation when applied to pointers is very fast.

It may be beneficial to apply pointers() to the result of slice(), to only operate on the necessary subset of elements.

Parameters
ccontainer of elements
Returns
a container of pointers to elements in the argument container

◆ reverse()

template<typename C >
auto sca::reverse ( C &&  c)

return a container where the order of elements is the reverse of the input container

Parameters
can input container
Returns
a new container with elements reversed from the input container

◆ size()

template<typename C >
size_t sca::size ( C &&  c)

return an iterable container's size, regardless if it implements a size() method

Parameters
ca container
Returns
the size of the container

◆ slice() [1/3]

template<typename C >
auto sca::slice ( C &&  c,
size_t  idx,
size_t  len 
)

create a slice_of object from a container which allows iteration over a subset of another container

This implementation only gets selected when the input container is an rvalue. The slice_of object will keep the original container in memory as long as the slice_of object exists.

Typical usecase is to use auto as the returned variable's type:

auto my_slice = sca::slice(my_container, 0, 13);
auto my_result = sca::map(my_function, my_slice);
auto slice(C &&c, size_t idx, size_t len)
create a slice_of object from a container which allows iteration over a subset of another container
Definition: scalgorithm.hpp:510

Or to use the slice inline:

auto my_result = sca::map(my_function, sca::slice(my_container, 0, 13));
Parameters
idxstarting index of the range of values
lenlength of range represented by slice
ccontainer to take slice of
Returns
a slice object capable of iterating a given container

◆ slice() [2/3]

template<typename C >
auto sca::slice ( C &  c,
size_t  idx,
size_t  len 
)

create a const_slice_of object from a container which allows iteration over a subset of another container

This is the lvalue reference implementation. Must return a const_slice_of in order to prevent inline uses of the slice() from treating the returned object as an rvalue. If a mutable slice_of object is required, call mslice() instead.

◆ slice() [3/3]

template<typename C >
auto sca::slice ( const C &  c,
size_t  idx,
size_t  len 
)

create a const_slice_of object from a container which allows iteration over a subset of another container

This is the const lvalue reference implementation.

◆ some()

template<typename F , typename C , typename... Cs>
bool sca::some ( F &&  f,
C &&  c,
Cs &&...  cs 
)

evaluate if a function returns true with at least one of the elements of containers grouped by index

Evaluation ends when traversible element in container c has been iterated.

Each container can contain a different value type as long as the value type can be passed to the function.

Parameters
fa predicate function applied to elements of input containers
cthe first container whose elements will have f applied to
csthe optional remaining containers whose elements will have f applied to
Returns
true if f returns true for at least one iterated element, else false

◆ sort()

template<typename C , typename F >
auto sca::sort ( C &&  c,
F &&  cmp 
)

return a container whose elements are sorted based on a comparison Callable

Parameters
ccontainer whose elements will be copied and sorted in the output
cmpa function which must accept two elements from the container and return a boolean
Returns
a sorted container of elements

◆ values()

template<typename C >
auto sca::values ( C &&  c)

return a container of deep value copies (never pointers) from a container of values or pointers

If input argument is a container of pointers, those pointers are dereferenced before copying.

Useful when operations on the result of a call to sca::pointers() are complete and a copy of pointed values is required. It is also useful when copying an arbitrary container or slice into a vector.

Parameters
ca container of values or pointers
Returns
a container of value copies