emlabcpp
modern opinionated embedded C++ library
message.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "../concepts.h"
27 #include "../view.h"
28 
29 #ifdef EMLABCPP_USE_NLOHMANN_JSON
30 #include <nlohmann/json.hpp>
31 #endif
32 
33 namespace emlabcpp::protocol
34 {
35 
38 template < std::size_t N >
39 class message
40 {
41 public:
43  using reference = std::byte&;
44  using pointer = std::byte*;
45  using const_pointer = std::byte const*;
46  using iterator = std::byte*;
47  using const_iterator = std::byte const*;
48  using size_type = std::size_t;
49 
50  static constexpr size_type capacity = N;
51 
52  constexpr message() = default;
53 
54  constexpr explicit message( size_type const n ) noexcept
55  : used_( n )
56  {
57  }
58 
59  constexpr explicit message( view< const_iterator > const& v ) noexcept
60  : used_( v.size() )
61  {
62  std::copy( v.begin(), v.end(), std::data( data_ ) );
63  }
64 
65  template < size_type M >
66  constexpr explicit message( message< M > const& other ) noexcept
67  : message( view{ other } )
68  {
69  static_assert( M <= N );
70  }
71 
72  template < size_type M >
73  constexpr explicit message( std::array< value_type, M > const& inpt ) noexcept
74  : message( view{ inpt } )
75  {
76  static_assert( M <= N );
77  }
78 
79  template < std::convertible_to< uint8_t >... Ts >
80  constexpr explicit message( Ts... inpt )
81  : data_{ static_cast< value_type >( inpt )... }
82  , used_( sizeof...( Ts ) )
83  {
84  }
85 
86  template < size_type M >
87  constexpr message& operator=( message< M > const& other ) noexcept
88  {
89  used_ = other.size();
90  std::copy( other.begin(), other.end(), std::data( data_ ) );
91  return *this;
92  }
93 
94  [[nodiscard]] constexpr const_pointer data() const noexcept
95  {
96  return &data_[0];
97  }
98 
99  [[nodiscard]] constexpr pointer data() noexcept
100  {
101  return &data_[0];
102  }
103 
104  [[nodiscard]] constexpr size_type size() const noexcept
105  {
106  return used_;
107  }
108 
109  [[nodiscard]] constexpr value_type front() const noexcept
110  {
111  return data_[0];
112  }
113 
114  [[nodiscard]] constexpr reference front() noexcept
115  {
116  return data_[0];
117  }
118 
119  [[nodiscard]] constexpr value_type back() const noexcept
120  {
121  return data_[used_ - 1];
122  }
123 
124  [[nodiscard]] constexpr reference back() noexcept
125  {
126  return data_[used_ - 1];
127  }
128 
129  [[nodiscard]] constexpr const_iterator begin() const noexcept
130  {
131  return &data_[0];
132  }
133 
134  [[nodiscard]] constexpr iterator begin() noexcept
135  {
136  return &data_[0];
137  }
138 
139  [[nodiscard]] constexpr const_iterator end() const noexcept
140  {
141  return &data_[0] + used_;
142  }
143 
144  [[nodiscard]] constexpr iterator end() noexcept
145  {
146  return &data_[0] + used_;
147  }
148 
149  value_type operator[]( size_type const i ) const noexcept
150  {
151  return data_[i];
152  }
153 
154  reference operator[]( size_type const i ) noexcept
155  {
156  return data_[i];
157  }
158 
159  void resize( size_type const n ) noexcept
160  {
161  used_ = n;
162  }
163 
164  friend auto operator==( message const& lh, message const& rh ) noexcept
165  {
166  return view_n( lh.begin(), lh.used_ ) == view_n( rh.begin(), rh.used_ );
167  }
168 
169 private:
170  std::byte data_[N];
171  size_type used_ = { 0 };
172 };
173 
174 template < std::convertible_to< uint8_t >... Ts >
175 message( Ts... inpt ) -> message< sizeof...( Ts ) >;
176 
181 template < std::size_t N >
182 class sizeless_message : public message< N >
183 {
184 public:
185  using message< N >::message;
186 
187  template < std::size_t M >
188  explicit sizeless_message( message< M > const& other )
189  : message< N >( other )
190  {
191  static_assert( M <= N );
192  }
193 };
194 
195 template < std::convertible_to< uint8_t >... Ts >
196 sizeless_message( Ts... inpt ) -> sizeless_message< sizeof...( Ts ) >;
197 
198 namespace detail
199 {
200  template < std::size_t N >
201  constexpr bool message_derived_test( message< N > const& )
202  {
203  return true;
204  }
205 } // namespace detail
206 
208 template < typename T >
210 
211 #ifdef EMLABCPP_USE_NLOHMANN_JSON
212 
213 template < std::size_t N >
214 void to_json( nlohmann::json& j, message< N > const& msg )
215 {
216  j = nlohmann::json::array();
217  for ( std::byte b : msg )
218  j.push_back( b );
219 }
220 
221 template < std::size_t N >
222 void from_json( nlohmann::json const& j, message< N >& msg )
223 {
224  if ( j.size() > N )
225  throw std::exception{}; // TODO: fix this
226 
227  std::vector< std::byte > tmp;
228  for ( std::byte const b : j )
229  tmp.push_back( b );
230 
231  msg = message< N >{ view< std::byte const* >( tmp ) };
232 }
233 
234 #endif
235 
236 } // namespace emlabcpp::protocol
The bounded class represents a wrapper over type T constrained between MinVal and MaxVal as compile-t...
Definition: bounded.h:44
Protocol library has custom type that represents message, however this is just simple overaly over st...
Definition: message.h:40
std::byte const * const_pointer
Definition: message.h:45
constexpr reference back() noexcept
Definition: message.h:124
constexpr message(size_type const n) noexcept
Definition: message.h:54
constexpr iterator begin() noexcept
Definition: message.h:134
constexpr const_iterator begin() const noexcept
Definition: message.h:129
value_type operator[](size_type const i) const noexcept
Definition: message.h:149
constexpr message & operator=(message< M > const &other) noexcept
Definition: message.h:87
constexpr const_pointer data() const noexcept
Definition: message.h:94
std::byte & reference
Definition: message.h:43
constexpr message(Ts... inpt)
Definition: message.h:80
static constexpr size_type capacity
Definition: message.h:50
constexpr pointer data() noexcept
Definition: message.h:99
std::byte * pointer
Definition: message.h:44
reference operator[](size_type const i) noexcept
Definition: message.h:154
constexpr size_type size() const noexcept
Definition: message.h:104
friend auto operator==(message const &lh, message const &rh) noexcept
Definition: message.h:164
constexpr message(view< const_iterator > const &v) noexcept
Definition: message.h:59
void resize(size_type const n) noexcept
Definition: message.h:159
std::byte * iterator
Definition: message.h:46
std::size_t size_type
Definition: message.h:48
constexpr value_type back() const noexcept
Definition: message.h:119
std::byte value_type
Definition: message.h:42
constexpr iterator end() noexcept
Definition: message.h:144
constexpr message(std::array< value_type, M > const &inpt) noexcept
Definition: message.h:73
constexpr const_iterator end() const noexcept
Definition: message.h:139
std::byte const * const_iterator
Definition: message.h:47
constexpr value_type front() const noexcept
Definition: message.h:109
constexpr message()=default
constexpr message(message< M > const &other) noexcept
Definition: message.h:66
constexpr reference front() noexcept
Definition: message.h:114
Sizeless message is class that behaves in a same way as normal message, however it is serialized diff...
Definition: message.h:183
sizeless_message(message< M > const &other)
Definition: message.h:188
Generic class to represent view of some container.
Definition: view.h:41
constexpr bool message_derived_test(message< N > const &)
Definition: message.h:201
MIT License.
Definition: multiplexer.h:33
sizeless_message(Ts... inpt) -> sizeless_message< sizeof...(Ts) >
requires(std::is_enum_v< T >) struct serializer< T
concept message_derived
concept matches any type that is message or derives from it.
Definition: message.h:209
message(Ts... inpt) -> message< sizeof...(Ts) >
constexpr pointer data() noexcept
Returns pointer to first item of the storage.
Definition: static_storage.h:108
void copy(Container &&cont, Iterator iter)
Definition: algorithm.h:455
constexpr view< Iter > view_n(Iter begin, std::size_t const n)
Creates view over 'n' items of dataset starting at 'begin' This does not check validity of the range!
Definition: view.h:198
N
Definition: static_storage.h:97
physical_quantity< 0, 0, 0, 0, 0, 0, 0, 0, 1 > byte
Definition: physical_quantity.h:118