emlabcpp
modern opinionated embedded C++ library
sequencer.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "../assert.h"
27 #include "../quantity.h"
28 #include "../static_circular_buffer.h"
29 
30 #include <array>
31 
32 namespace emlabcpp::protocol
33 {
34 
35 struct sequencer_read_request : quantity< sequencer_read_request, std::size_t >
36 {
37  using quantity::quantity;
38 };
39 
40 template < typename Def >
41 class sequencer
42 {
43 public:
44  static constexpr auto prefix = Def::prefix;
45  static constexpr std::size_t fixed_size = Def::fixed_size;
46 
47 private:
49 
50 public:
51  using message_type = typename Def::message_type;
52 
53  template < typename Container >
54  void insert( Container&& dview )
55  {
56  copy( std::forward< Container >( dview ), std::back_inserter( buffer_ ) );
57  }
58 
59  std::variant< sequencer_read_request, message_type > get_message()
60  {
61  auto bend = buffer_.end();
62  while ( !buffer_.empty() ) {
63  auto [piter, biter] =
64  std::mismatch( prefix.begin(), prefix.end(), buffer_.begin(), bend );
65 
67  if ( biter == buffer_.begin() ) {
68  buffer_.pop_front();
69  continue;
70  }
71 
73  if ( piter != prefix.end() && biter != bend ) {
74  buffer_.pop_front();
75  continue;
76  }
77 
79  if ( piter != prefix.end() ) {
81  fixed_size - static_cast< std::size_t >(
82  std::distance( prefix.begin(), piter ) ) };
83  }
84 
85  break;
86  }
87 
88  if ( buffer_.empty() )
90 
91  std::size_t const bsize = buffer_.size();
92 
95  EMLABCPP_ASSERT( bsize >= prefix.size() );
96 
97  if ( bsize < fixed_size )
98  return sequencer_read_request{ fixed_size - bsize };
99 
100  std::size_t const desired_size = Def::get_size( buffer_ );
101  if ( bsize < desired_size )
102  return sequencer_read_request{ desired_size - bsize };
103 
104  message_type res( desired_size );
105  copy( view_n( buffer_.begin(), desired_size ), res.begin() );
106 
108  for ( std::size_t i = desired_size; i > 0; i-- )
109  buffer_.pop_front();
110 
111  return res;
112  }
113 };
114 
115 template < typename Sequencer, typename ReadCallback >
116 std::optional< typename Sequencer::message_type >
117 sequencer_simple_load( std::size_t const read_limit, ReadCallback&& read )
118 {
119  Sequencer seq;
120  std::optional< typename Sequencer::message_type > res;
121  std::size_t to_read = Sequencer::fixed_size;
122  std::size_t count = 0;
123  while ( !res && count < read_limit ) {
124  std::optional data = read( to_read );
125  if ( !data )
126  return res;
127  seq.insert( *data );
128  seq.get_message().match(
129  [&to_read, &count]( std::size_t const next_read ) {
130  to_read = next_read;
131  count = 0;
132  },
133  [&res]( auto msg ) {
134  res = msg;
135  } );
136 
137  count += 1;
138  }
139  return res;
140 }
141 
142 } // namespace emlabcpp::protocol
#define EMLABCPP_ASSERT(cond)
MIT License.
Definition: assert.h:38
Definition: sequencer.h:42
typename Def::message_type message_type
Definition: sequencer.h:51
static constexpr auto prefix
Definition: sequencer.h:44
std::variant< sequencer_read_request, message_type > get_message()
Definition: sequencer.h:59
static constexpr std::size_t fixed_size
Definition: sequencer.h:45
void insert(Container &&dview)
Definition: sequencer.h:54
Class representing generic quantity.
Definition: quantity.h:63
constexpr quantity() noexcept
Definition: quantity.h:79
size_type size() const
Definition: static_circular_buffer.h:212
bool empty() const
Definition: static_circular_buffer.h:223
iterator end()
methods for handling the back side of the circular buffer
Definition: static_circular_buffer.h:158
void pop_front()
Definition: static_circular_buffer.h:142
iterator begin()
methods for handling the front side of the circular buffer
Definition: static_circular_buffer.h:104
MIT License.
Definition: multiplexer.h:33
std::optional< typename Sequencer::message_type > sequencer_simple_load(std::size_t const read_limit, ReadCallback &&read)
Definition: sequencer.h:117
constexpr std::size_t count(Container &&cont, UnaryCallable &&f=std::identity())
Applies the predicate 'f(x)' to each element of container 'cont' and returns the count of items,...
Definition: algorithm.h:234
length distance
Definition: physical_quantity.h:129
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
T res
Definition: algorithm.h:505