12 #ifdef MICROSTRAIN_HAS_OPTIONAL 
   16 #if __cpp_lib_apply >= 201603L 
   54     SerializerBase(uint8_t* ptr, 
size_t capacity, 
size_t offset=0) : m_ptr(ptr), m_size(capacity), m_offset(offset) {}
 
   55     SerializerBase(
const uint8_t* ptr, 
size_t size, 
size_t offset=0) : m_ptr(const_cast<uint8_t*>(ptr)), m_size(size), m_offset(offset) {}
 
   58     size_t capacity()
   const { 
return m_size;                 }  
 
   59     size_t offset()
     const { 
return m_offset;               }  
 
   60     size_t usedLength()
 const { 
return offset();               }  
 
   61     int remaining()
     const { 
return int(m_size - m_offset); }  
 
   63     bool isOverrun()
                  const { 
return m_offset > m_size;        }  
 
   64     bool isOk()
                       const { 
return !isOverrun();             }  
 
   65     bool isFinished()
                 const { 
return m_offset == m_size;       }  
 
   66     bool hasRemaining(
size_t count=0)
 const { 
return m_offset+count <= m_size; }  
 
   68     uint8_t*       basePointer()       { 
return m_ptr; }  
 
   69     const uint8_t* basePointer()
 const { 
return m_ptr; }  
 
   75     uint8_t*       
pointer(
size_t required_size)       { 
return hasRemaining(required_size) ? (m_ptr+m_offset) : 
nullptr; }
 
   76     const uint8_t* 
pointer(
size_t required_size)
 const { 
return hasRemaining(required_size) ? (m_ptr+m_offset) : 
nullptr; }  
 
   88     uint8_t* 
getPtrAndAdvance(
size_t size) { uint8_t* ptr = hasRemaining(size) ? (m_ptr+m_offset) : 
nullptr; m_offset += size; 
return ptr; }
 
   99     size_t setOffset(
size_t offset) { std::swap(m_offset, offset); 
return offset; }
 
  102     uint8_t* m_ptr    = 
nullptr;
 
  124 template<serialization::Endian E>
 
  132     template<
typename... Ts> 
bool insert (
const Ts&... values);
 
  133     template<
typename... Ts> 
bool extract(Ts&... values);
 
  135     template<
class T, 
class S> 
bool extract_count(T& count, S max_count);
 
  170 template<serialization::Endian E, 
class T>
 
  171 typename std::enable_if<std::is_arithmetic<T>::value, 
size_t>::type
 
  175         serialization::write<E>(ptr, value);
 
  191 template<serialization::Endian E, 
class T>
 
  192 typename std::enable_if<std::is_arithmetic<T>::value, 
size_t>::type
 
  196         serialization::read<E>(ptr, value);
 
  219 template<serialization::Endian E, 
class T>
 
  220 typename std::enable_if<std::is_enum<T>::value, 
size_t>::type
 
  223     using BaseType = 
typename std::underlying_type<T>::type;
 
  226         serialization::write<E>(ptr, 
static_cast<BaseType
>(value));
 
  228     return sizeof(BaseType);
 
  244 template<serialization::Endian E, 
class T>
 
  245 typename std::enable_if<std::is_enum<T>::value, 
size_t>::type
 
  248     using BaseType = 
typename std::underlying_type<T>::type;
 
  253         serialization::read<E>(ptr, base);
 
  254         value = 
static_cast<T
>(base);
 
  257     return sizeof(BaseType);
 
  297 template<serialization::Endian E, 
class T, decltype(&T::insert) = 
nullptr>
 
  298 typename std::enable_if<std::is_class<T>::value , 
size_t>::type
 
  301     size_t offset = serializer.offset();
 
  302     object.
insert(serializer);
 
  303     return serializer.offset() - offset;
 
  338 template<serialization::Endian E, 
class T, decltype(&T::extract) = 
nullptr>
 
  339 typename std::enable_if<std::is_class<T>::value , 
size_t>::type
 
  342     size_t offset = serializer.offset();
 
  344     return serializer.offset() - offset;
 
  357 #if __cpp_lib_apply >= 201603L 
  373 size_t insert(Serializer<E>& serializer, 
const std::tuple<Ts...>& values)
 
  375     auto lambda = [&serializer](
const Ts&... args) {
 
  376         return insert(serializer, args...);
 
  379     return std::apply(lambda, values);
 
  396 size_t extract(Serializer<E>& serializer, 
const std::tuple<std::reference_wrapper<Ts>...>& values)
 
  398     auto lambda = [&serializer](
auto&... args) {
 
  399         return extract(serializer, args...);
 
  402     return std::apply(lambda, values);
 
  425 template<serialization::Endian E, 
class T>
 
  431         const size_t size = 
sizeof(T)*count;
 
  434             for(
size_t i=0; i<count; i++)
 
  435                 serialization::write<E>(ptr+i*
sizeof(T), values[i]);
 
  441         size_t offset = serializer.offset();
 
  442         for(
size_t i=0; i<count; i++)
 
  443             serializer.
insert(values[i]);
 
  444         return serializer.offset() - offset;
 
  460 template<serialization::Endian E, 
class T>
 
  466         const size_t size = 
sizeof(T)*count;
 
  469             for(
size_t i=0; i<count; i++)
 
  470                 serialization::read<E>(ptr+i*
sizeof(T), values[i]);
 
  476         size_t offset = serializer.offset();
 
  477         for(
size_t i=0; i<count; i++)
 
  479         return serializer.offset() - offset;
 
  494 template<serialization::Endian E, 
class T>
 
  511 template<serialization::Endian E, 
class T>
 
  533 template<serialization::Endian E, 
class T, 
size_t N>
 
  536     return insert(serializer, values, N);
 
  550 template<serialization::Endian E, 
class T, 
size_t N>
 
  553     return extract(serializer, values, N);
 
  569 template<serialization::Endian E, 
class T, 
size_t N>
 
  572     return insert(serializer, values.data(), values.size());
 
  586 template<serialization::Endian E, 
class T, 
size_t N>
 
  589     return extract(serializer, values.data(), values.size());
 
  612 #if __cpp_fold_expressions >= 201603L && __cpp_if_constexpr >= 201606L 
  614 typename std::enable_if<(
sizeof...(Ts) > 1), 
size_t>::type
 
  615  insert(Serializer<E>& serializer, Ts... values)
 
  617     if constexpr( (std::is_arithmetic<Ts>::value && ...) )
 
  619         const size_t size = ( ... + 
sizeof(Ts) );
 
  621         if(uint8_t* ptr = serializer.getPtrAndAdvance(size))
 
  624             ( ..., (offset += serialization::write<E>(ptr+offset, values)) );
 
  631         return ( ... + 
insert(serializer, values) );
 
  637     return insert(serializer, value0) + 
insert(serializer, value1, values...);
 
  658 #if __cpp_fold_expressions >= 201603L && __cpp_if_constexpr >= 201606L 
  660 typename std::enable_if<(
sizeof...(Ts) > 1), 
size_t>::type
 
  661  extract(Serializer<E>& serializer, Ts&... values)
 
  663     if constexpr( (std::is_arithmetic<Ts>::value && ...) )
 
  665         const size_t size = ( ... + 
sizeof(Ts) );
 
  667         if(uint8_t* ptr = serializer.getPtrAndAdvance(size))
 
  670             ( ..., (offset += serialization::read<E>(ptr+offset, values)) );
 
  677         return ( ... + 
extract(serializer, values) );
 
  683     return extract(serializer, value0) + 
extract(serializer, value1, values...);
 
  721 template<serialization::Endian E, 
class T>
 
  722 bool insert(
const T& value, uint8_t* buffer, 
size_t buffer_length, 
size_t offset=0, 
bool exact_size=
false)
 
  726     return exact_size ? serializer.isFinished() : serializer.isOk();
 
  759 template<serialization::Endian E, 
class T>
 
  760 bool extract(T& value, 
const uint8_t* buffer, 
size_t buffer_length, 
size_t offset=0, 
bool exact_size=
false)
 
  764     return exact_size ? serializer.isFinished() : serializer.isOk();
 
  790 template<serialization::Endian E, 
class T>
 
  793     return insert<E,T>(value, buffer.
data(), buffer.
size(), offset, exact_size);
 
  814 template<serialization::Endian E, 
class T>
 
  817     return extract<E,T>(value, buffer.
data(), buffer.
size(), offset, exact_size);
 
  824 #ifdef MICROSTRAIN_HAS_OPTIONAL 
  825 template<
class T, serialization::Endian E>
 
  838 std::optional<T> 
extract(Serializer<E>& serializer)
 
  841     if(extract<E,T>(serializer, value))
 
  864 template<
class T, serialization::Endian E>
 
  865 std::optional<T> 
extract(
const uint8_t* buffer, 
size_t length, 
size_t offset, 
bool exact_size=
false)
 
  868     if(extract<E,T>(value, buffer, length, offset, exact_size))
 
  890 template<
class T, serialization::Endian E>
 
  894     if(extract<E,T>(value, buffer.
data(), buffer.
size(), offset, exact_size))
 
  921 template<serialization::Endian E>
 
  922 template<
typename... Ts>
 
  947 template<serialization::Endian E>
 
  948 template<
typename... Ts>
 
  978 template<serialization::Endian E>
 
  979 template<
class T, 
class S>
 
  984         if( count <= max_count )