@@ -192,15 +192,16 @@ private static void generateGroupClassHeader(
192192 final  int  blockLength  = tokens .get (index ).encodedLength ();
193193 final  Token  blockLengthToken  = Generators .findFirst ("blockLength" , tokens , index );
194194 final  Token  numInGroupToken  = Generators .findFirst ("numInGroup" , tokens , index );
195-  final  String  cppTypeForBlockLength  = cppTypeName (blockLengthToken .encoding ().primitiveType ());
196-  final  String  cppTypeForNumInGroup  = cppTypeName (numInGroupToken .encoding ().primitiveType ());
195+  final  String  cppTypeBlockLength  = cppTypeName (blockLengthToken .encoding ().primitiveType ());
196+  final  String  cppTypeNumInGroup  = cppTypeName (numInGroupToken .encoding ().primitiveType ());
197197
198198 new  Formatter (sb ).format ("\n "  +
199199 indent  + "class %1$s\n "  +
200200 indent  + "{\n "  +
201201 indent  + "private:\n "  +
202202 indent  + " char *m_buffer = nullptr;\n "  +
203203 indent  + " std::uint64_t m_bufferLength = 0;\n "  +
204+  indent  + " std::uint64_t m_initialPosition = 0;\n "  +
204205 indent  + " std::uint64_t *m_positionPtr = nullptr;\n "  +
205206 indent  + " std::uint64_t m_blockLength = 0;\n "  +
206207 indent  + " std::uint64_t m_count = 0;\n "  +
@@ -228,8 +229,9 @@ private static void generateGroupClassHeader(
228229 indent  + " m_bufferLength = bufferLength;\n "  +
229230 indent  + " m_blockLength = dimensions.blockLength();\n "  +
230231 indent  + " m_count = dimensions.numInGroup();\n "  +
231-  indent  + " m_index = std::numeric_limits<std::uint64_t>::max() ;\n "  +
232+  indent  + " m_index = 0 ;\n "  +
232233 indent  + " m_actingVersion = actingVersion;\n "  +
234+  indent  + " m_initialPosition = *pos;\n "  +
233235 indent  + " m_positionPtr = pos;\n "  +
234236 indent  + " *m_positionPtr = *m_positionPtr + %1$d;\n "  +
235237 indent  + " }\n " ,
@@ -262,14 +264,18 @@ private static void generateGroupClassHeader(
262264 indent  + " %7$s dimensions(buffer, *pos, bufferLength, actingVersion);\n "  +
263265 indent  + " dimensions.blockLength((%1$s)%2$d);\n "  +
264266 indent  + " dimensions.numInGroup((%3$s)count);\n "  +
265-  indent  + " m_index = std::numeric_limits<std::uint64_t>::max() ;\n "  +
267+  indent  + " m_index = 0 ;\n "  +
266268 indent  + " m_count = count;\n "  +
267269 indent  + " m_blockLength = %2$d;\n "  +
268270 indent  + " m_actingVersion = actingVersion;\n "  +
271+  indent  + " m_initialPosition = *pos;\n "  +
269272 indent  + " m_positionPtr = pos;\n "  +
270273 indent  + " *m_positionPtr = *m_positionPtr + %4$d;\n "  +
271274 indent  + " }\n " ,
272-  cppTypeForBlockLength , blockLength , cppTypeForNumInGroup , dimensionHeaderLength ,
275+  cppTypeBlockLength ,
276+  blockLength ,
277+  cppTypeNumInGroup ,
278+  dimensionHeaderLength ,
273279 minCheck ,
274280 numInGroupToken .encoding ().applicableMaxValue ().longValue (),
275281 dimensionsClassName );
@@ -311,25 +317,41 @@ private static void generateGroupClassHeader(
311317
312318 indent  + " SBE_NODISCARD inline bool hasNext() const SBE_NOEXCEPT\n "  +
313319 indent  + " {\n "  +
314-  indent  + " return m_index + 1  < m_count;\n "  +
320+  indent  + " return m_index < m_count;\n "  +
315321 indent  + " }\n \n "  +
316322
317323 indent  + " inline %3$s &next()\n "  +
318324 indent  + " {\n "  +
325+  indent  + " if (m_index >= m_count)\n "  +
326+  indent  + " {\n "  +
327+  indent  + " throw std::runtime_error(\" index >= count [E108]\" );\n "  +
328+  indent  + " }\n "  +
319329 indent  + " m_offset = *m_positionPtr;\n "  +
320330 indent  + " if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + m_blockLength) > m_bufferLength), false))\n "  +
321331 indent  + " {\n "  +
322-  indent  + " throw std::runtime_error(\" "  +
323-  "buffer too short to support next group index [E108]\" );\n "  +
332+  indent  + " throw std::runtime_error(\" buffer too short for next group index [E108]\" );\n "  +
324333 indent  + " }\n "  +
325334 indent  + " *m_positionPtr = m_offset + m_blockLength;\n "  +
326335 indent  + " ++m_index;\n \n "  +
327336
328337 indent  + " return *this;\n "  +
329338 indent  + " }\n " ,
330-  dimensionHeaderLength , blockLength , formatClassName (groupName ));
339+  dimensionHeaderLength ,
340+  blockLength ,
341+  formatClassName (groupName ));
342+ 
343+  sb .append ("\n " )
344+  .append (indent ).append (" inline std::uint64_t resetCountToIndex() SBE_NOEXCEPT\n " )
345+  .append (indent ).append (" {\n " )
346+  .append (indent ).append (" m_count = m_index;\n " )
347+  .append (indent ).append (" " ).append (dimensionsClassName )
348+  .append (" dimensions(m_buffer, m_initialPosition, m_bufferLength, m_actingVersion);\n " )
349+  .append (indent ).append (" dimensions.numInGroup((" ).append (cppTypeNumInGroup ).append (")m_count);\n " )
350+  .append (indent ).append (" return m_count;\n " )
351+  .append (indent ).append (" }\n " );
331352
332-  sb .append (indent ).append ("#if __cplusplus < 201103L\n " )
353+  sb .append ("\n " )
354+  .append (indent ).append ("#if __cplusplus < 201103L\n " )
333355 .append (indent ).append (" template<class Func> inline void forEach(Func& func)\n " )
334356 .append (indent ).append (" {\n " )
335357 .append (indent ).append (" while (hasNext())\n " )
0 commit comments