Commit f3b71b20 authored by Jan Koniarik's avatar Jan Koniarik
Browse files

improved documentation a bit

parent 82460547
Pipeline #106438 passed with stage
in 52 seconds
......@@ -9,15 +9,17 @@ The library is heavily used our core project and spread itself into other smalle
- [Installation](#Installation)
- [Components](#Components)
- [algorithm.h](#algorithm.h)
- [either.h](#either.h)
- [view.h](#view.h)
- [iterator.h](#iterator.h)
- [quantity.h](#quantity.h)
- [pid.h](#pid.h)
- [static_circular_buffer.h](#static_circular_buffer.h)
- [static_vector.h](#static_vector.h)
- [types.h](#types.h)
- [algorithm.h](#algorithmh)
- [either.h](#eitherh)
- [view.h](#viewh)
- [bounded.h](#boundedh)
- [protocol.h](#protocolh)
- [iterator.h](#iteratorh)
- [quantity.h](#quantityh)
- [pid.h](#pidh)
- [static_circular_buffer.h](#static_circular_bufferh)
- [static_vector.h](#static_vectorh)
- [types.h](#typesh)
## Installation
Repository is at https://gitlab.fi.muni.cz/xkoniar/emlabcpp and mirrored to github repository https://github.com/emlab-fi/emlabcpp.
......@@ -63,6 +65,8 @@ auto iter = find_if(vec_data, [&]( int i ){
```
See examples for an overview of algorithms.
### either.h
`either<A,B>` is `std::variant` alternative able to hold only two types.
......@@ -130,6 +134,46 @@ for(int i : reversed(vec_data))
std::cout << '\n';
```
### bounded.h
Simple overlay type for constraing value within specified range.
Makes it possible to create clear API that does not have to check the sanity of values.
`bounded<int,0,42>` means that the `bounded` class contains `int` type that is constrained within `0` and `42`.
The API with `bounded` has more clear intent:
```cpp
void foo(bounded<int,0,42>);
```
### protocol.h
The protocol library serializes and deserialize C++ data structures into binary messages.
The principle is that the protocol is defined with library types.
Based on the definition, `protocol_handler<Def>` provides routines for serialization and deserialization of data structures corresponding to said definition.
In case of work with simple robot, we can create simple protocol:
```cpp
using distance = unsigned;
using angle = int;
enum robot_cmds : uint8_t
{
FORWARD = 0,
LEFT = 1,
RIGHT = 2
}
struct robot_cmd_group
: protocol_command_group< PROTOCOL_LITTLE_ENDIAN >::with_commands<
protocol_command< FORWARD >::with_args< distance >,
protocol_command< LEFT >::with_args< angle >,
protocol_command< RIGHT >::with_args< angle >
>
{};
```
See examples for more detailed explanation.
### iterator.h
Contains `generic_iterator\<Derived\>` CRTP baseclass.
......
......@@ -10,6 +10,18 @@
namespace emlabcpp
{
/// Bounded type represents a overlay over type T which is constrained between MinVal and MaxVal as
/// compile time constants. / The API is deisgned in a way that you can't create the type out of
/// theb ounds.
///
/// This is beneficial in design of an API.
/// In case of using the T directly and asserting that it is withing corrent range, the API has to
/// check at runtime whenever that is true and return error in case it is out of range. / With
/// bounded type the API does not have to do that, as the type can't be passed unless it is within
/// corret range.
///
/// It does not remove the bounds check, it just moves it away from within API to the user, which
/// has to deal with creating correct bounded type.
template < typename T, T MinVal, T MaxVal >
class bounded
{
......@@ -33,6 +45,8 @@ public:
{
}
// Static method that creates an instance of bounded with value provided at compile time.
// This value is checked at compile time.
template < T Val >
static constexpr bounded get()
{
......@@ -40,6 +54,8 @@ public:
return bounded{ Val };
}
// Static method optinally returns bounded value, only in case the input value is withing
// allowed range.
template < typename U >
static std::optional< bounded< T, min_val, max_val > > make( U val )
{
......@@ -77,11 +93,13 @@ public:
return val_;
}
// Rotation to the right increases the internal value by step modulo the range it is in.
void rotate_right( T step )
{
val_ = min_val + ( val_ + step - min_val ) % ( max_val - min_val );
}
// Rotation to the left decreases the internal value by step modulo the range it is in.
void rotate_left( T step )
{
val_ = min_val + ( val_ - step - min_val ) % ( max_val - min_val );
......@@ -90,19 +108,21 @@ public:
friend constexpr auto operator<=>( const bounded&, const bounded& ) = default;
// template < std::totally_ordered_with< T > U >
// so, we can't have nice things... ^^ if the type of U is constrained this way, the
// compiler will get into infinite recursion when trying to _test_ it in case we use <=> on
// identical bounded types
template < typename U >
friend constexpr auto operator<=>( const bounded& b, const U& val )
{
// so, we can't have nice things... ^^ if the type of U is constrained this way, the
// compiler will get into infinite recursion when trying to _test_ it in case we use
// <=> on identical bounded types
return *b <=> val;
}
};
// Simple type alias for bounded index constants.
template < std::size_t N >
constexpr auto bounded_constant = bounded< std::size_t, N, N >{};
// Sum of two bounded types of same base type is bounded within appropiate ranges.
template < typename T, T FromLh, T ToLh, T FromRh, T ToRh >
constexpr bounded< T, FromLh + FromRh, ToLh + ToRh >
operator+( const bounded< T, FromLh, ToLh >& lh, const bounded< T, FromRh, ToRh >& rh )
......@@ -119,6 +139,7 @@ namespace detail
}
} // namespace detail
// Concept that matchestype deriving from bounded
template < typename T >
concept bounded_derived = requires( T val )
{
......@@ -129,11 +150,7 @@ concept bounded_derived = requires( T val )
template < typename T, T MinVal, T MaxVal >
std::ostream& operator<<( std::ostream& os, const bounded< T, MinVal, MaxVal >& b )
{
if constexpr ( std::is_same_v< T, uint8_t > ) {
return os << int( *b );
} else {
return os << *b;
}
return os << *b;
}
#endif
......
#include "emlabcpp/algorithm.h"
#include "emlabcpp/algorithm_detail.h"
#include "emlabcpp/either.h"
#include "emlabcpp/iterator.h"
#include "emlabcpp/physical_quantity.h"
#include "emlabcpp/quantity.h"
#include "emlabcpp/static_circular_buffer.h"
#include "emlabcpp/types.h"
#include "emlabcpp/view.h"
#include "emlabcpp/zip.h"
#pragma once
// dummy file that serves as main header file including everything
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment