Guest User

serial.hpp

a guest
May 21st, 2018
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.24 KB | None | 0 0
  1. // TODO: probaby unrelated to ranges, but
  2. #pragma once
  3.  
  4. #include <algorithm>
  5. #include "ranger.hpp"
  6.  
  7. #include "endian.h"
  8. #if __BYTE_ORDER != __LITTLE_ENDIAN
  9. #error "big endian architecture not supported"
  10. #endif
  11.  
  12. namespace serial {
  13.     template <typename E, bool BE = false, typename R>
  14.     auto peek (const R& r) {
  15.         using T = typename R::value_type;
  16.  
  17.         static_assert(std::is_same<T, uint8_t>::value, "this is custom message");
  18.         static_assert(sizeof(E) % sizeof(T) == 0, "this is custom message");
  19.  
  20.         constexpr auto count = sizeof(E) / sizeof(T);
  21.         assert(count <= r.size());
  22.  
  23.         E value;
  24.         auto copy = range(r);
  25.         auto ptr = reinterpret_cast<T*>(&value);
  26.  
  27.         if (BE) {
  28.             for (size_t i = 0; i < count; ++i, copy.popFront()) ptr[count - 1 - i] = copy.front();
  29.         } else {
  30.             for (size_t i = 0; i < count; ++i, copy.popFront()) ptr[i] = copy.front();
  31.         }
  32.  
  33.         return value;
  34.     }
  35.  
  36.     template <typename E, bool BE = false, typename R>
  37.     void place (R& r, const E e) {
  38.         using T = typename R::value_type;
  39.  
  40.         static_assert(std::is_same<T, uint8_t>::value, "this is custom message");
  41.         static_assert(sizeof(E) % sizeof(T) == 0, "this is custom message");
  42.  
  43.         constexpr auto count = sizeof(E) / sizeof(T);
  44.         assert(count <= r.size());
  45.  
  46.         auto copy = range(r);
  47.         auto ptr = reinterpret_cast<const T*>(&e);
  48.  
  49.         if (BE) {
  50.             for (size_t i = 0; i < count; ++i, copy.popFront()) copy.front() = ptr[count - 1 - i];
  51.         } else {
  52.             for (size_t i = 0; i < count; ++i, copy.popFront()) copy.front() = ptr[i];
  53.         }
  54.     }
  55.  
  56.     template <typename E, bool BE = false, typename R>
  57.     auto read (R& r) {
  58.         using T = typename R::value_type;
  59.  
  60.         const auto e = peek<E, BE, R>(r);
  61.         r.popFrontN(sizeof(E) / sizeof(T));
  62.         return e;
  63.     }
  64.  
  65.     template <typename E, bool BE = false, typename R>
  66.     void put (R& r, const E e) {
  67.         using T = typename R::value_type;
  68.  
  69.         place<E, BE, R>(r, e);
  70.         r.popFrontN(sizeof(E) / sizeof(T));
  71.     }
  72.  
  73.     // rvalue references wrappers
  74.     template <typename E, bool BE = false, typename R> void place (R&& r, const E e) { place<E, BE, R>(r, e); }
  75.     template <typename E, bool BE = false, typename R> auto read (R&& r) { return read<E, BE, R>(r); }
  76.     template <typename E, bool BE = false, typename R> void put (R&& r, const E e) { put<E, BE, R>(r, e); }
  77. }
Add Comment
Please, Sign In to add comment