12 #ifdef MICROSTRAIN_HAS_OPTIONAL 
   16 #if __cpp_lib_apply >= 201603L 
   64     SerializerBase(uint8_t* ptr, 
size_t capacity) : m_ptr(ptr), m_size(capacity), m_offset(0) {}
 
   65     SerializerBase(
const uint8_t* ptr, 
size_t size) : m_ptr(const_cast<uint8_t*>(ptr)), m_size(size), m_offset(0) {}
 
   68     size_t capacity()
   const { 
return m_size;                 }  
 
   69     size_t offset()
     const { 
return m_offset;               }  
 
   70     size_t usedLength()
 const { 
return offset();               }  
 
   71     int    remaining()
  const { 
return int(m_size - m_offset); }  
 
   73     bool isOverrun()
                  const { 
return m_offset > m_size;        }  
 
   74     bool isOk()
                       const { 
return !isOverrun();             }  
 
   75     bool isFinished()
                 const { 
return m_offset == m_size;       }  
 
   76     bool hasRemaining(
size_t count=1)
 const { 
return m_offset+count <= m_size; }  
 
   78     uint8_t*       basePointer()       { 
return m_ptr; }  
 
   79     const uint8_t* basePointer()
 const { 
return m_ptr; }  
 
   85     uint8_t*       
getPointer(
size_t required_size)       { 
return hasRemaining(required_size) ? (m_ptr+m_offset) : 
nullptr; }
 
   86     const uint8_t* 
getPointer(
size_t required_size)
 const { 
return hasRemaining(required_size) ? (m_ptr+m_offset) : 
nullptr; }  
 
   98     uint8_t* 
getPtrAndAdvance(
size_t size) { uint8_t* ptr = hasRemaining(size) ? (m_ptr+m_offset) : 
nullptr; m_offset += size; 
return ptr; }
 
  109     size_t setOffset(
size_t offset) { std::swap(m_offset, offset); 
return offset; }
 
  112     uint8_t* m_ptr    = 
nullptr;
 
  134 template<serialization::Endian E>
 
  142     template<
typename... Ts> 
bool insert (
const Ts&... values);
 
  143     template<
typename... Ts> 
bool extract(Ts&... values);
 
  145     template<
class T, 
class S> 
bool extract_count(T& count, S max_count);
 
  180 template<serialization::Endian E, 
class T>
 
  181 typename std::enable_if<std::is_arithmetic<T>::value, 
size_t>::type
 
  185         serialization::write<E>(ptr, value);
 
  201 template<serialization::Endian E, 
class T>
 
  202 typename std::enable_if<std::is_arithmetic<T>::value, 
size_t>::type
 
  206         serialization::read<E>(ptr, value);
 
  229 template<serialization::Endian E, 
class T>
 
  230 typename std::enable_if<std::is_enum<T>::value, 
size_t>::type
 
  233     using BaseType = 
typename std::underlying_type<T>::type;
 
  236         serialization::write<E>(ptr, 
static_cast<BaseType
>(value));
 
  238     return sizeof(BaseType);
 
  254 template<serialization::Endian E, 
class T>
 
  255 typename std::enable_if<std::is_enum<T>::value, 
size_t>::type
 
  258     using BaseType = 
typename std::underlying_type<T>::type;
 
  263         serialization::read<E>(ptr, base);
 
  264         value = 
static_cast<T
>(base);
 
  267     return sizeof(BaseType);
 
  307 template<serialization::Endian E, 
class T, decltype(&T::insert) = 
nullptr>
 
  308 typename std::enable_if<std::is_class<T>::value , 
size_t>::type
 
  311     size_t offset = serializer.offset();
 
  312     object.
insert(serializer);
 
  313     return serializer.offset() - offset;
 
  348 template<serialization::Endian E, 
class T, decltype(&T::extract) = 
nullptr>
 
  349 typename std::enable_if<std::is_class<T>::value , 
size_t>::type
 
  352     size_t offset = serializer.offset();
 
  354     return serializer.offset() - offset;
 
  367 #if __cpp_lib_apply >= 201603L 
  383 size_t insert(Serializer<E>& serializer, 
const std::tuple<Ts...>& values)
 
  385     auto lambda = [&serializer](
const Ts&... args) {
 
  386         return insert(serializer, args...);
 
  389     return std::apply(lambda, values);
 
  406 size_t extract(Serializer<E>& serializer, 
const std::tuple<std::reference_wrapper<Ts>...>& values)
 
  408     auto lambda = [&serializer](
auto&... args) {
 
  409         return extract(serializer, args...);
 
  412     return std::apply(lambda, values);
 
  435 template<serialization::Endian E, 
class T>
 
  441         const size_t size = 
sizeof(T)*count;
 
  444             for(
size_t i=0; i<count; i++)
 
  445                 serialization::write<E>(ptr+i*
sizeof(T), values[i]);
 
  451         size_t offset = serializer.offset();
 
  452         for(
size_t i=0; i<count; i++)
 
  453             serializer.
insert(values[i]);
 
  454         return serializer.offset() - offset;
 
  470 template<serialization::Endian E, 
class T>
 
  476         const size_t size = 
sizeof(T)*count;
 
  479             for(
size_t i=0; i<count; i++)
 
  480                 serialization::read<E>(ptr+i*
sizeof(T), values[i]);
 
  486         size_t offset = serializer.offset();
 
  487         for(
size_t i=0; i<count; i++)
 
  489         return serializer.offset() - offset;
 
  504 template<serialization::Endian E, 
class T>
 
  521 template<serialization::Endian E, 
class T>
 
  543 template<serialization::Endian E, 
class T, 
size_t N>
 
  546     return insert(serializer, values, N);
 
  560 template<serialization::Endian E, 
class T, 
size_t N>
 
  563     return extract(serializer, values, N);
 
  579 template<serialization::Endian E, 
class T, 
size_t N>
 
  582     return insert(serializer, values.data(), values.size());
 
  596 template<serialization::Endian E, 
class T, 
size_t N>
 
  599     return extract(serializer, values.data(), values.size());
 
  622 #if __cpp_fold_expressions >= 201603L && __cpp_if_constexpr >= 201606L 
  624 typename std::enable_if<(
sizeof...(Ts) > 1), 
size_t>::type
 
  625  insert(Serializer<E>& serializer, Ts... values)
 
  627     if constexpr( (std::is_arithmetic<Ts>::value && ...) )
 
  629         const size_t size = ( ... + 
sizeof(Ts) );
 
  631         if(uint8_t* ptr = serializer.getPtrAndAdvance(size))
 
  634             ( ..., (offset += serialization::write<E>(ptr+offset, values)) );
 
  641         return ( ... + 
insert(serializer, values) );
 
  647     return insert(serializer, value0) + 
insert(serializer, value1, values...);
 
  668 #if __cpp_fold_expressions >= 201603L && __cpp_if_constexpr >= 201606L 
  670 typename std::enable_if<(
sizeof...(Ts) > 1), 
size_t>::type
 
  671  extract(Serializer<E>& serializer, Ts&... values)
 
  673     if constexpr( (std::is_arithmetic<Ts>::value && ...) )
 
  675         const size_t size = ( ... + 
sizeof(Ts) );
 
  677         if(uint8_t* ptr = serializer.getPtrAndAdvance(size))
 
  680             ( ..., (offset += serialization::read<E>(ptr+offset, values)) );
 
  687         return ( ... + 
extract(serializer, values) );
 
  693     return extract(serializer, value0) + 
extract(serializer, value1, values...);
 
  731 template<serialization::Endian E, 
class T>
 
  732 bool insert(
const T& value, uint8_t* buffer, 
size_t buffer_length, 
size_t offset=0, 
bool exact_size=
false)
 
  737     return exact_size ? serializer.isFinished() : serializer.isOk();
 
  770 template<serialization::Endian E, 
class T>
 
  771 bool extract(T& value, 
const uint8_t* buffer, 
size_t buffer_length, 
size_t offset=0, 
bool exact_size=
false)
 
  776     return exact_size ? serializer.isFinished() : serializer.isOk();
 
  802 template<serialization::Endian E, 
class T>
 
  805     return insert<E,T>(value, buffer.
data(), buffer.
size(), offset, exact_size);
 
  826 template<serialization::Endian E, 
class T>
 
  829     return extract<E,T>(value, buffer.
data(), buffer.
size(), offset, exact_size);
 
  836 #ifdef MICROSTRAIN_HAS_OPTIONAL 
  837 template<
class T, serialization::Endian E>
 
  850 std::optional<T> 
extract(Serializer<E>& serializer)
 
  853     if(extract<E,T>(serializer, value))
 
  876 template<
class T, serialization::Endian E>
 
  877 std::optional<T> 
extract(
const uint8_t* buffer, 
size_t length, 
size_t offset, 
bool exact_size=
false)
 
  880     if(extract<E,T>(value, buffer, length, offset, exact_size))
 
  902 template<
class T, serialization::Endian E>
 
  906     if(extract<E,T>(value, buffer.
data(), buffer.
size(), offset, exact_size))
 
  933 template<serialization::Endian E>
 
  934 template<
typename... Ts>
 
  959 template<serialization::Endian E>
 
  960 template<
typename... Ts>
 
  990 template<serialization::Endian E>
 
  991 template<
class T, 
class S>
 
  996         if( count <= max_count )