Utility library
#include "crow/types.hpp"
namespace Crow;
#define CROW_ASSERT(expr)
#define CROW_XASSERT(expr)
Assertion macros. CROW_ASSERT() does the same thing as the standard
assert() macro, except that it is not suppressed by defining NDEBUG.
CROW_XASSERT() performs the same test, but throws an AssertionFailure
exception instead of printing a message and aborting on failure.
using std::int8_t;
using std::int16_t;
using std::int32_t;
using std::int64_t;
using std::uint8_t;
using std::uint16_t;
using std::uint32_t;
using std::uint64_t;
using std::ptrdiff_t;
using std::size_t;
Imported for convenience.
using Callback = std::function<void()>;
Defined for convenience.
template <std::totally_ordered T>
std::strong_ordering compare3way(const T& a, const T& b) noexcept;
Performs a 3-way comparison by calling operator<=> if available, otherwise
operator== and operator<.
constexpr std::strong_ordering to_order(ArithmeticType auto t) noexcept;
Converts a number to a strong ordering value: negative numbers map to less,
zero to equal, and positive numbers to greater.
(Several of these are replacements for C++20 standard concepts that are not yet supported by all compilers, and will be removed when this is fixed.)
template <typename T> concept ArithmeticType;
Satisfied by any integral or floating point type, except bool.
template <typename T> concept BitwiseType;
Satisfied by a type that implements the bitwise operators ~ & | ^.
template <typename T> concept NumericType;
template <typename T> concept IntegralNumericType;
template <typename T> concept NonIntegralNumericType;
NumericType is satisfied by any type for which a specialisation of
std::numeric_limits exists. The other concepts break this down into
integral and non-integral types.
template <typename T> concept PrimitiveScalarType;
Satisfied if T is a primitive scalar type.
template <typename T, typename U> concept SameBasicType;
Satisfied if T and U are the same type apart from any CV and reference
qualifications.
template <typename T> concept ThreeWayComparable;
Satisfied if T supports the <=> operator.
template <typename T>
concept UniqueCloneable = std::has_virtual_destructor_v<T>
&& requires (const T& obj) {
{ obj.clone() } -> std::convertible_to<std::unique_ptr<T>>;
};
template <typename T>
concept SharedCloneable = std::has_virtual_destructor_v<T>
&& ! UniqueCloneable<T>
&& requires (const T& obj) {
{ obj.clone() } -> std::convertible_to<std::shared_ptr<T>>;
};
template <typename T>
concept Cloneable = UniqueCloneable<T> || SharedCloneable<T>;
Satisfied if T is the root class of a cloneable hierarchy.
template <typename T> concept IteratorType;
Satisfied if T is an iterator.
template <typename T> concept MutableIteratorType;
Satisfied if T is a mutable iterator.
template <typename T> concept RangeType;
template <typename T> concept MutableRangeType;
Satisfied if T is a range, defined as having begin(T) and end(T)
functions that can be found either by ADL or in namespace std.
template <typename T> concept MaplikeRangeType;
template <typename T> concept MutableMaplikeRangeType;
Satisfied if T is a range, and its value type has first and second data
members. The MutableMaplikeRangeType concept only requires the second
member to be mutable.
template <typename T> concept InputIteratorType;
template <typename T> concept MutableInputIteratorType;
template <typename T> concept InputRangeType;
template <typename T> concept MutableInputRangeType;
template <typename T> concept OutputIteratorType;
template <typename T> concept MutableOutputIteratorType;
template <typename T> concept OutputRangeType;
template <typename T> concept MutableOutputRangeType;
template <typename T> concept ForwardIteratorType;
template <typename T> concept MutableForwardIteratorType;
template <typename T> concept ForwardRangeType;
template <typename T> concept MutableForwardRangeType;
template <typename T> concept BidirectionalIteratorType;
template <typename T> concept MutableBidirectionalIteratorType;
template <typename T> concept BidirectionalRangeType;
template <typename T> concept MutableBidirectionalRangeType;
template <typename T> concept RandomAccessIteratorType;
template <typename T> concept MutableRandomAccessIteratorType;
template <typename T> concept RandomAccessRangeType;
template <typename T> concept MutableRandomAccessRangeType;
These indicate whether an iterator type, or the iterator type of a range, meets the requirements for one of the standard iterator concepts. Each of these will be satisfied if the iterator’s category is at least equal to the named category.
template <typename T> concept SimpleContainerType;
template <typename T> concept AssociativeContainerType;
template <typename T> concept ContiguousContainerType;
Simplified container concepts. These do not attempt to match all the formal
requirements of the standard container concepts. SimpleContainerType checks
for:
T::value_type, T::iterator, T::const_iteratort.empty(), t.size()t.begin(), t.end()t.clear()t.insert(it, value)t.erase(it)(Note that SimpleContainerType does not match std::array or
std::forward_list.)
AssociativeContainerType is a refinement of SimpleContainerType that also
checks for:
T::key_type, T::mapped_typevalue.first, value.secondt[key]t.contains(key), t.count(key), t.erase(key), t.find(key)ContiguousContainerType matches SimpleContainerType and
std::ranges::contiguous_range.
constexpr size_t npos = std::string::npos;
Imported for convenience.
class AssertionFailure: public std::runtime_error {
AssertionFailure(std::string_view expression, std::string_view function,
std::string_view file, int line);
std::string expression() const;
std::string function() const;
std::string file() const;
int line() const noexcept;
};
The exception thrown when a CROW_XASSERT() fails.
template <typename T = void, typename U = T> struct Plus; // +
template <typename T = void, typename U = T> struct Minus; // -
template <typename T = void, typename U = T> struct Multiplies; // *
template <typename T = void, typename U = T> struct Divides; // /
template <typename T = void, typename U = T> struct Modulus; // %
template <typename T = void, typename U = T> struct BitAnd; // &
template <typename T = void, typename U = T> struct BitOr; // |
template <typename T = void, typename U = T> struct BitXor; // ^
Heterogeneous versions of the standard function objects for binary arithmetic
operations. Like those, these have void specializations with a templated
function call operator.
namespace Literals {
template <char... CS> constexpr int8_t operator""_s8() noexcept;
template <char... CS> constexpr int16_t operator""_s16() noexcept;
template <char... CS> constexpr int32_t operator""_s32() noexcept;
template <char... CS> constexpr int64_t operator""_s64() noexcept;
template <char... CS> constexpr uint8_t operator""_u8() noexcept;
template <char... CS> constexpr uint16_t operator""_u16() noexcept;
template <char... CS> constexpr uint32_t operator""_u32() noexcept;
template <char... CS> constexpr uint64_t operator""_u64() noexcept;
template <char... CS> constexpr ptrdiff_t operator""_z() noexcept;
template <char... CS> constexpr size_t operator""_uz() noexcept;
}
Integer literals. The standard 0b and 0x prefixes are understood, and
apostrophe delimiters are allowed.
struct FreeMem {
void operator()(void* ptr) const noexcept;
};
A deleter (suitable for use with smart pointers) that calls std::free().
template <typename T> using RangeIterator = [iterator type];
template <typename T> using RangeValue = [value type];
The iterator and value types of a range, or void if T is not a range.
template <typename T, bool B> struct SfinaeTrue {};
template <typename T> struct SfinaeTrue<T, true>: std::true_type {};
Creates an artificial dependency to allow enable_if to be used in contexts
that are not directly dependent.
template <typename T> constexpr bool dependent_false = false;
Allows compile time failure in an if constexpr branch.
template <typename T, typename U, Cloneable V = U>
requires (std::derived_from<U, V>)
class BasicClone:
public U {
[smart pointer type] clone() const override;
};
Deriving a class T from BasicClone<T,U[,V]> implicitly derives T from
U and defines the T::clone() function (which calls the copy constructor).
The third template argument is used when a multilevel hierarchy is desired,
and the immediate base class U is not the same as the root class V.