Public Library Components
Exceptions
ALl exceptions thrown by this library that aren’t part of the STL’s suite of exceptions will be of the type svs::ANNException
described below.
-
ANNEXCEPTION(format, ...)
Construct an exception with line information.
Data Types
-
enum class DataType
Enum aliases for dense vector element types.
Values:
-
enumerator uint8
-
enumerator uint16
-
enumerator uint32
-
enumerator uint64
-
enumerator int8
-
enumerator int16
-
enumerator int32
-
enumerator int64
-
enumerator float16
-
enumerator float32
-
enumerator float64
-
enumerator byte
-
enumerator undef
-
enumerator uint8
-
template<DataType Type>
using cpp_type_t = typename detail::CppType<Type>::type Convert an DataType to its corresponding C++ type.
-
template<typename T>
constexpr DataType datatype_v = detail::datatype_v<std::decay_t<T>> Convert a C++ type into its corresponding DataType.
-
template<typename T>
constexpr bool has_datatype_v = (datatype_v<T> != DataType::undef) Return whether the type
T
has a correspondingsvs::DataType
.
-
template<DataType Type>
constexpr std::string_view name() Return a descriptive name for the corresponding datatype.
Static and Dynamic Dimensionality
Vector abstractions in the library often come with the ability to statically type dimensionality (i.e., the number of elements in a vector). When static dimensionality is used, the compiler/library can often generate better code resulting in substantial speedups. Unfortunately, there is no free lunch as specializing functions for specific dimensionalities results in extra compilation time and code generation. Therefore, we include the option for both static (compile time) and dynamic (run time) dimensionality for internal vectors.
-
const size_t Dynamic = std::dynamic_extent
Special value representing run-time dimensionality.
Throughout the code base, static size information for various vector types can be passed to potentially improve the quality of generated code.
While this can be beneficial at runtime, it does come at the cost of increased compilation time and the need to dispatch to specialized implementations if they exist.
When run-time dimensionality is desired instead, the use of the sentinel value
Dynamic
can be used.
-
template<size_t N>
class Val - #include <svs/lib/meta.h>
Compile-time dimensionality.
If dynamic (i.e. runtime) dimensionality is required, set
N = svs::Dynamic
.- Template Parameters:
N – - The static number of dimensions.
Types
The library has support for passing either types or lists of types explicitly to some functions. Often, this works better than relying on positional type parameters of those respective functions as these classes can be passed for any argument and are generally more flexible.
-
template<typename T, typename ...Ts>
constexpr bool in(Types<Ts...> typelist = {}) Return whether the requested type is in the type list.
-
template<typename ...Ts>
constexpr bool in(DataType datatype, Types<Ts...> typelist = {}) Return whether the requested runtime type is in the compiletime type list.
Requires that elements in the type list have a know corresponding data type.
- Parameters:
datatype – The runtime data type.
typelist – The list of accepted types.
-
template<typename F, typename ...Ts>
constexpr void for_each_type(Types<Ts...> types, F &&f) Generator helper for each type.
- Parameters:
types – - The list of types to pass to the functor
f
.f – - Functor accepting a single argument
Type<T>
called once for eachT
intypes
.
-
template<typename T>
struct Type - #include <svs/lib/meta.h>
Empty struct for reasoning about types.
- Template Parameters:
T – - The C++ type this struct refers to.
-
template<typename ...Ts>
struct Types - #include <svs/lib/meta.h>
A list of types.
Public Static Functions
Example
An example of using types is given below.
In this example, we’ll show usage of svs::lib::Types
and svs::lib::for_each_type
.
First, we include the appropriate headers:
#include "svs/lib/datatype.h"
#include "svs/lib/float16.h"
#include "svs/lib/meta.h"
#include <cstdint>
#include <iostream>
The “svs” headers include the following:
datatype.h
: Type enums and naming for common C++ data types.meta.h
: Defines theTypes
classfloat16.h
: Support for 16-bit floating point.
With those included, we can define our main function.
int main() {
auto types = svs::lib::Types<int64_t, float, svs::Float16>();
// Print out the name of each type.
svs::lib::for_each_type(types, []<typename T>(svs::lib::Type<T> /*svs_type*/) {
// Print out the name of the data type.
std::cout << svs::name<svs::datatype_v<T>>() << '\n';
});
}
We first construct the variable types
as a type list with three parameters. Then, we invoke svs::lib::for_each_type
on the resulting object. To this function, we also pass a lambda accepting a single argument of type 8 svs::lib::Type
. This lambda is called for each type in types
’ parameter pack. The resulting output will be:
int64
float32
float16
The full code example is given below.
#include "svs/lib/datatype.h"
#include "svs/lib/float16.h"
#include "svs/lib/meta.h"
#include <cstdint>
#include <iostream>
int main() {
auto types = svs::lib::Types<int64_t, float, svs::Float16>();
// Print out the name of each type.
svs::lib::for_each_type(types, []<typename T>(svs::lib::Type<T> /*svs_type*/) {
// Print out the name of the data type.
std::cout << svs::name<svs::datatype_v<T>>() << '\n';
});
}
Memory Management
Reading and Writing to Streams
-
template<typename T, typename Stream>
size_t svs::lib::write_binary(Stream &stream, const T &val) Write the canonical binary representation of
val
to the output stream.Writing will occur sequentially on each byte beginning from the least significant byte.
Accepted types:
Any
std::is_trivially_copyable
type.A
std::vector
orstd::span
of such types.
- Parameters:
stream – A
std::basic_ostream
compatible object.j:waval – The value to write.
- Returns:
The number of bytes written to the stream.
-
template<typename T, typename Stream>
void read_binary(Stream &stream, T &x) Read the canonical binary representation of
T
and store the results inx
.Accepted types
T
:Any type satisfying
std::is_trivially_copyable
. Parameterx
will the be populated as if bystd::memcpy
.A
std::vector
of such types. Each element of the vector will be populated as if by recursively callingsvs::lib::read_binary
on each element beginning from the beginning.
- Parameters:
stream – A
std::istream
compatible object.x – The destination to store the result.
-
template<typename T, typename Stream>
T read_binary(Stream &stream) Read the canonical binary representation of
T
.Read the canonical binary representation of
T
as if bystd::memcpy
. Requires thatT
satisfiesstd::is_trivially_copyable
.- Template Parameters:
T – The type to read from the stream.
- Parameters:
stream – A
std::istream
compatible object.