36 template <std::
size_t Bytes, byte_order Order>
40 Order == byte_order::little_endian ||
41 Order == byte_order::big_endian,
42 "Specified byte order not implemented");
46 "Specified byte count not implemented");
49 enum{ value_mask = (~static_cast <uint64_t> (0)) >> (64 - 8*Bytes) };
50 enum{ value_shift = 8*Bytes };
51 enum{ offset = (Order == byte_order::big_endian ? 8*(Bytes-1) : 0) };
52 enum{ multiplier = (Order == byte_order::big_endian ? -8 : 8) };
54 template <
unsigned int State, std::
size_t N, std::
size_t Index = 0>
58 static uint64_t run (
unsigned char const* s)
60 enum{ shift = offset + multiplier*((State + Index) % Bytes) };
61 return (static_cast <uint64_t> (*s) << shift) | unroll <State, N, Index+1>::run(s+1);
65 template <
unsigned int State, std::
size_t N>
66 struct unroll <State, N, N>
69 static uint64_t run (
unsigned char const*)
75 template <std::
size_t N>
78 template <std::
size_t I,
typename T>
80 bool operator() (T* this_ptr,
unsigned char const* s)
82 enum{ new_state = (I+N) % Bytes };
83 enum{ loop_count = N / Bytes };
84 enum{ remainder = N % Bytes };
86 for (
unsigned int i=0; i < loop_count; ++i, s += Bytes)
87 this_ptr->add(unroll <I, Bytes>::run(s));
89 this_ptr->add(unroll <I, remainder>::run(s));
90 this_ptr->p_iState = new_state;
96 bool operator() (T*,
unsigned char const*)
102 struct handler_dynamic
104 template <std::
size_t I,
typename T>
106 bool operator() (T* this_ptr,
unsigned char const* s, std::size_t n)
108 this_ptr->p_iState = (I + n) % Bytes;
110 for (; n >= Bytes; s += Bytes, n -= Bytes)
111 this_ptr->add(unroll <I, Bytes>::run(s));
115 case 7:
return this_ptr->add(unroll <I, 7>::run(s));
116 case 6:
return this_ptr->add(unroll <I, 6>::run(s));
117 case 5:
return this_ptr->add(unroll <I, 5>::run(s));
118 case 4:
return this_ptr->add(unroll <I, 4>::run(s));
119 case 3:
return this_ptr->add(unroll <I, 3>::run(s));
120 case 2:
return this_ptr->add(unroll <I, 2>::run(s));
121 case 1:
return this_ptr->add(unroll <I, 1>::run(s));
123 default: assert(
false);
127 template <
typename T>
129 bool operator() (T*,
unsigned char const*, std::size_t)
139 template <std::
size_t N>
143 auto const ptr = reinterpret_cast <
unsigned char const*> (s);
144 return variadic_switch_return <values> (p_iState, handler_fixed <N> (),
this, ptr);
150 bool write (
char const* s, std::size_t n)
153 auto const ptr = reinterpret_cast <
unsigned char const*> (s);
154 return variadic_switch_return <values> (p_iState, handler_dynamic(),
this, ptr, n);
164 uint64_t result = p_iSum;
165 while (result >> value_shift)
166 result = (result & value_mask) + (result >> value_shift);
168 return (~result) & value_mask;
181 bool add (uint64_t x)
183 auto const result = p_iSum + x;
184 p_iSum = result + (result < x);
191 unsigned int p_iState {0};
194 using internet_checksum = modular_sum <2, byte_order::big_endian>;
198 #include <framework/serializable/streams/modular_sum.inl>