Utilities

Misc helper functionality.

likely

likely(expr)

Marks the given expression to likely be evaluated to true.

This may help compiler optimization.

Returns:

the evaluated expr

unlikely(expr)

Marks the given expression to likely be evaluated to true.

This may help compiler optimization.

Returns:

the evaluated expr

saturated_cast

template<typename R, typename T>
R saturated_cast(T value) noexcept

Converts a number type to another one, with proper rounding and saturation.

stored_assert

stored_assert(expr)

Like assert(), but only emits code when stored::Config::EnableAssert.

stored::banner

char const *stored::banner() noexcept

Return a single-line string that contains relevant configuration information of libstored.

stored::Fifo

template<typename T, size_t Capacity = 0, bool ThreadSafe = (Capacity > 0)>
class Fifo

FIFO that is optionally bounded in size and optionally thread-safe.

This is a single-producer single-consumer FIFO.

If bounded (Capacity is non-zero), it implements a circular buffer and does not do dynamic memory allocation during operation. Then, it is thread-safe and async-signal safe. Therefore, it can be used to communicate between threads, but also by an interrupt handler.

If unbounded, it cannot be thread-safe.

Public Types

typedef PopIterator<Fifo> iterator
typedef Buffer_type::pointer pointer
typedef T type

Public Functions

inline size_t available() const noexcept
inline constexpr iterator begin() noexcept
inline constexpr bool bounded() const noexcept
inline constexpr size_t capacity() const noexcept
inline void clear()
template<typename ...Arg>
inline void emplace_back(Arg&&... arg)
inline bool empty() const noexcept
inline constexpr iterator end() noexcept
inline type const &front() const noexcept
inline type &front() noexcept
inline bool full() const noexcept
inline type const &operator[](size_t offset) const noexcept
inline type &operator[](size_t offset) noexcept
inline type const &peek(size_t offset) const noexcept
inline type &peek(size_t offset) noexcept
inline void pop_front(size_t count = 1) noexcept
template<typename It>
inline void push_back(It start, It end)
inline void push_back(std::initializer_list<type> init)
inline void push_back(T const &x)
inline void push_back(type const *value, size_t len)
inline constexpr size_t size() const noexcept
inline size_t space() const noexcept

stored::memcmp_swap

int stored::memcmp_swap(void const *a, void const *b, size_t len) noexcept

memcmp() with endianness swapping.

void stored::memcpy_swap(void *dst, void const *src, size_t len) noexcept

memcpy() with endianness swapping.

stored::MessageFifo

template<size_t Capacity = 0, size_t Messages = impl::defaultMessages(Capacity), bool ThreadSafe = (Capacity > 0)>
class MessageFifo

FIFO for arbitrary-length messages.

This is a single-producer single-consumer FIFO.

The FIFO can be unbounded (Capacity is zero), which allows queuing any number and length of messages. However, it cannot be thread-safe in that case.

If the FIFO is bounded (Capacity is set to the total buffer size for all queued messages), it can queue any number of messages (but limited by Messages) of any size (up to Capacity). Messages of different length can be used. It does not use dynamic memory allocation. It can be configured to be thread-safe, which is also async-signal safe. Therefore, it can be used to pass messages between threads, but also from/to an interrupt handler.

Public Types

typedef MessageView const_type
typedef PopIterator<MessageFifo> iterator
typedef Message type

Public Functions

inline bool append_back(char const *message, size_t length)
inline bool append_back(const_type const &message)
inline size_t available() const noexcept
inline constexpr iterator begin() noexcept
inline constexpr bool bounded() const noexcept
inline constexpr size_t capacity() const noexcept
inline void clear()
inline bool empty() const noexcept
inline constexpr iterator end() noexcept
inline const_type front() const noexcept
inline type front() noexcept
inline bool full() const noexcept
inline void pop_back()
inline void pop_front() noexcept
inline bool push_back()
inline bool push_back(char const *message, size_t length)
inline bool push_back(const_type const &message)
template<typename It>
inline size_t push_back(It start, It end)
inline size_t push_back(std::initializer_list<const_type> init)
inline void reset_back()
inline constexpr size_t size() const noexcept
inline size_t space() const noexcept

stored::Scratchpad

template<size_t MaxSize = 0xffff>
class ScratchPad

Memory that uses bump-alloc for a very fast short-lived heap.

The ScratchPad grows automatically, but it is more efficient to manage the capacity() on beforehand. The capacity is determined while using the ScratchPad, which may cause some more overhead at the start of the application.

There is no overhead per alloc(), but padding bytes may be inserted to word-align allocs. Heap fragmentation is not possible.

Alloc is very fast, but dealloc or free is not possible. Bump-alloc is like a stack; you can reset() it, or make a snapshot(), which you can rollback to.

Template Parameters:

MaxSize – the maximum total size to be allocated, which is used to determine the type of the internal counters.

Public Types

enum [anonymous]

Values:

enumerator maxSize

Maximum total size of allocated memory.

enumerator chunkHeader

Size of the header of a chunk.

enumerator spare

Extra amount to reserve when the chunk is allocated.

typedef value_type<MaxSize>::type size_type

Type of all internally used size counters.

Public Functions

inline explicit ScratchPad(size_t reserve = 0)

Ctor.

Parameters:

reserve – number of bytes to reserve during construction

inline ~ScratchPad() noexcept

Dtor.

template<typename T>
inline T *alloc(size_t count = 1, size_t align = sizeof(T))

Allocate memory.

Template Parameters:

T – the type of object to allocate

Parameters:
  • count – number of objects, which is allocated as an array of T

  • align – alignment requirement (maximized to word size)

Returns:

a pointer to the allocated memory, which remains uninitialized and cannot be nullptr

inline constexpr size_t capacity() const noexcept

Returns the total capacity currently available within the ScratchPad.

inline constexpr size_t chunks() const noexcept

Returns the number of chunks of the ScratchPad.

You would want to have only one chunk, but during the first moments of running, the ScratchPad has to determine how much memory the application uses. During this time, there may exist multiple chunks. Call reset() to optimize memory usage.

inline constexpr bool empty() const noexcept

Checks if the ScratchPad is empty.

inline constexpr size_t max() const noexcept

Returns the maximum size.

To reset this value, use shrink_to_fit().

inline void reserve(size_t more)

Reserves memory to save the additional given amount of bytes.

inline void reset() noexcept

Resets the content of the ScratchPad.

Coalesce chunks when required. It leaves max() untouched. To actually free all used memory, call shrink_to_fit() afterwards.

inline void shrink_to_fit() noexcept

Releases all unused memory back to the OS, if possible.

inline constexpr size_t size() const noexcept

Returns the total amount of allocated memory.

This includes padding because of alignment requirements of alloc().

inline Snapshot snapshot() noexcept

Get a snapshot of the ScratchPad.

Friends

friend class Snapshot
class Snapshot

A snapshot of the ScratchPad, which can be rolled back to.

A Snapshot remains valid, until the ScratchPad is reset, or an earlier snapshot is rolled back. An invalid snapshot cannot be rolled back, and cannot be destructed, as that implies a rollback. Make sure to reset the snapshot before destruction, if it may have become invalid.

Normally, you would let a snapshot go out of scope before doing anything with older snapshots.

Public Functions

inline Snapshot(Snapshot &&s) noexcept

Move ctor.

inline Snapshot(Snapshot const &s) noexcept

Move ctor.

Even though s is const, it will be reset anyway by this ctor.

inline ~Snapshot() noexcept

Dtor, which implies a rollback.

inline Snapshot &operator=(Snapshot &&s) noexcept

Move-assign.

Snapshot &operator=(Snapshot const &s) = delete
inline void reset() noexcept

Detach from the ScratchPad.

Cannot rollback afterwards.

inline void rollback() noexcept

Perform a rollback of the corresponding ScratchPad.

stored::Signal

template<typename Key = void*, typename Token = void*, typename ...Args>
class Signal

Public Types

using Callable_type = typename Callable<callback_type>::type
using callback_type = void(Args...)
using Connection = std::pair<token_type, Callable_type>
using ConnectionMap = typename UnorderedMultiMap<key_type, Connection>::type
using key_type = Key
using size_type = typename ConnectionMap::size_type
using token_type = Token

Public Functions

Signal() = default
inline explicit Signal(size_type bucket_count)
inline void call(Args... args) const
inline void call(Key key, Args... args) const
template<typename F, SFINAE_IS_FUNCTION(F, callback_type, int) = 0>
inline void connect(F &&f, token_type token = NoToken)
template<typename F, SFINAE_IS_FUNCTION(F, callback_type, int) = 0>
inline void connect(key_type key, F &&f, token_type token = NoToken)
inline bool connected() const noexcept
inline bool connected(key_type key) const
inline void disconnect()
inline void disconnect(key_type key)
inline void disconnect(key_type key, token_type token)
template<typename ...Args_>
inline void operator()(Args_&&... args) const
template<typename ...Args_>
inline void operator()(Key key, Args_&&... args) const
inline void reserve(size_type count)

Public Static Attributes

static constexpr key_type NoKey = impl::noKey<Key>()
static constexpr token_type NoToken = Token{}

stored::Signalling

template<typename Base>
class Signalling : public Base

A wrapper that allows calling a function when a variable changes.

It maintains a single std::unordered_multimap from a registered variable key to a function.

Public Types

using callback_type = typename Signal_type::callback_type
using Key = typename Base::Key
using Signal_type = Signal<Key>
using Token = typename Signal_type::token_type

Public Functions

~Signalling() = default
inline void __hookExitX(Type::type type, void *buffer, size_t len, bool changed) noexcept
template<typename Store, typename Implementation, typename T, size_t offset, size_t size_, typename F, SFINAE_IS_FUNCTION(F, callback_type, int) = 0, typename std::enable_if<std::is_base_of<Store, Base>::value, int>::type = 0>
inline void connect(impl::StoreVariable<Store, Implementation, T, offset, size_> &var, F &&f, Token token = Signal_type::NoToken)
template<typename Store, typename Implementation, Type::type type_, size_t offset, size_t size_, typename F, SFINAE_IS_FUNCTION(F, callback_type, int) = 0, typename std::enable_if<std::is_base_of<Store, Base>::value, int>::type = 0>
inline void connect(impl::StoreVariantV<Store, Implementation, type_, offset, size_> &var, F &&f, Token token = Signal_type::NoToken)
template<typename Store, typename Implementation, typename T, size_t offset, size_t size_>
inline void disconnect(impl::StoreVariable<Store, Implementation, T, offset, size_> &var, Token token = Signal_type::NoToken)
template<typename Store, typename Implementation, Type::type type_, size_t offset, size_t size_>
inline void disconnect(impl::StoreVariantV<Store, Implementation, type_, offset, size_> &var, Token token = Signal_type::NoToken)

stored::string_literal

String::type stored::string_literal(void const *buffer, size_t len, char const *prefix)

Converts the given buffer to a string literal.

This comes in handy for verbose output of binary data, like protocol messages.

stored::strncmp

int stored::strncmp(char const *str1, size_t len1, char const *str2, size_t len2) noexcept

Like strncmp(), but handles non zero-terminated strings.

stored::strncpy

size_t stored::strncpy(char *dst, char const *src, size_t len) noexcept

Like strncpy(), but without padding and returning the length of the string.

stored::swap_endian

template<typename T>
static inline T stored::swap_endian(T value) noexcept

Swap endianness of the given value.

void stored::swap_endian(void *buffer, size_t len) noexcept

Swap endianness of the given buffer.