@@ -45,17 +45,17 @@ static uint16_t const max_surrogate_high = 0xDBFF;
4545static uint16_t const min_surrogate_low = 0xDC00 ;
4646static uint16_t const max_surrogate_low = 0xDFFF ;
4747
48- inline bool is_surrogate_high (uint32_t const cp)
48+ inline bool is_surrogate_high (uint32_t const cp) throw()
4949{
5050 return min_surrogate_high <= cp && cp <= max_surrogate_high;
5151}
5252
53- inline bool is_surrogate_low (uint32_t const cp)
53+ inline bool is_surrogate_low (uint32_t const cp) throw()
5454{
5555 return min_surrogate_low <= cp && cp <= max_surrogate_low;
5656}
5757
58- inline bool is_surrogate (uint32_t const cp)
58+ inline bool is_surrogate (uint32_t const cp) throw()
5959{
6060 return min_surrogate <= cp && cp <= max_surrogate;
6161}
@@ -69,32 +69,33 @@ struct utf8 final
6969 static_assert (max_code_point == (1u << 31 ) - 1u , " Invalid maximum supported code point" );
7070
7171 template <
72- typename It>
73- static size_t size (It & it)
72+ typename It,
73+ typename NextFn>
74+ static size_t sizech (It & it, NextFn && next_fn)
7475 {
75- uint8_t const chf = *it;
76+ uint8_t const chf = *it++ ;
7677 if (chf < 0x80 )
7778 return 1 ;
7879 else if (chf < 0xC0 )
7980 throw std::runtime_error (" Unexpected UTF8 slave symbol at master position" );
80- else if (chf < 0xE0 )
81+ else if (next_fn (it), chf < 0xE0 )
8182 return 2 ;
82- else if (chf < 0xF0 )
83+ else if (next_fn (it), chf < 0xF0 )
8384 return 3 ;
84- else if (chf < 0xF8 )
85+ else if (next_fn (it), chf < 0xF8 )
8586 return 4 ;
86- else if (chf < 0xFC )
87+ else if (next_fn (it), chf < 0xFC )
8788 return 5 ;
88- else if (chf < 0xFE )
89+ else if (next_fn (it), chf < 0xFE )
8990 return 6 ;
9091 else
9192 throw std::runtime_error (" Invalid UTF8 master symbol" );
9293 }
9394
9495 template <
9596 typename It,
96- typename VerifyIt >
97- static uint32_t read (It & it, VerifyIt && verify_it )
97+ typename VerifyFn >
98+ static uint32_t read (It & it, VerifyFn && verify_fn )
9899 {
99100 uint8_t const chf = *it++;
100101 if (chf < 0x80 ) // 0xxx_xxxx
@@ -132,7 +133,7 @@ struct utf8 final
132133 throw std::runtime_error (" Invalid UTF8 master symbol" );
133134 while (extra-- > 0 )
134135 {
135- verify_it ( );
136+ verify_fn (it );
136137 uint8_t const chn = *it++;
137138 if (chn < 0x80 || 0xC0 <= chn)
138139 throw std::runtime_error (" Invalid UTF8 slave symbol" );
@@ -196,29 +197,30 @@ struct utf16 final
196197 static_assert (max_code_point == 0x10000u + (1u << 20 ) - 1u , " Invalid maximum supported code point" );
197198
198199 template <
199- typename It>
200- static size_t size (It & it)
200+ typename It,
201+ typename NextFn>
202+ static size_t sizech (It & it, NextFn && next_fn)
201203 {
202- uint16_t const chf = *it;
204+ uint16_t const chf = *it++ ;
203205 if (chf < 0xD800 || 0xE000 <= chf)
204206 return 1 ;
205- else if (chf < 0xDC00 )
207+ else if (next_fn (it), chf < 0xDC00 )
206208 return 2 ;
207209 else
208210 throw std::runtime_error (" Unexpected UTF16 slave symbol at master position" );
209211 }
210212
211213 template <
212214 typename It,
213- typename VerifyIt >
214- static uint32_t read (It & it, VerifyIt && verify_it )
215+ typename VerifyFn >
216+ static uint32_t read (It & it, VerifyFn && verify_fn )
215217 {
216218 uint16_t const chf = *it++;
217219 if (chf < 0xD800 || 0xE000 <= chf) // [0x0000‥0xD7FF] or [0xE000‥0xFFFF]
218220 return chf;
219- else if (chf < 0xDC00 ) // [0xD800‥0xDBFF] [0xDC00‥0xDFFF]
221+ else if (chf < 0xDC00 ) // [0xD800‥0xDBFF] [0xDC00‥0xDFFF]
220222 {
221- verify_it ( );
223+ verify_fn (it );
222224 uint16_t const chn = *it++;
223225 if (chn < 0xDC00 || 0xE000 <= chn)
224226 throw std::runtime_error (" Invalid UTF16 slave symbol" );
@@ -258,16 +260,18 @@ struct utf32 final
258260 static_assert (max_code_point == (1u << 31 ) - 1u , " Invalid maximum supported code point" );
259261
260262 template <
261- typename It>
262- static size_t size (It &)
263+ typename It,
264+ typename NextFn>
265+ static size_t sizech (It & it, NextFn &&)
263266 {
267+ ++it;
264268 return 1 ;
265269 }
266270
267271 template <
268272 typename It,
269- typename VerifyIt >
270- static uint32_t read (It & it, VerifyIt &&)
273+ typename VerifyFn >
274+ static uint32_t read (It & it, VerifyFn &&)
271275 {
272276 return *it++;
273277 }
@@ -286,9 +290,36 @@ struct utf32 final
286290template <
287291 typename Utf,
288292 typename It>
289- size_t size (It it)
293+ size_t sizech (It it)
294+ {
295+ return Utf::sizech (it, [] (It &) {});
296+ }
297+
298+ template <
299+ typename Utf,
300+ typename It>
301+ size_t sizez (It it)
290302{
291- return Utf::size (it);
303+ size_t size = 0 ;
304+ while (*it)
305+ size += Utf::sizech (it, [] (It & it) { ++it; });
306+ return size;
307+ }
308+
309+ template <
310+ typename Utf,
311+ typename It>
312+ size_t size (It it, It const eit)
313+ {
314+ auto const next_fn = [&eit] (It & it)
315+ {
316+ if (it++ == eit)
317+ throw std::runtime_error (" Not enough input" );
318+ };
319+ size_t size = 0 ;
320+ while (it != eit)
321+ size += Utf::sizech (it, next_fn);
322+ return size;
292323}
293324
294325template <
@@ -300,7 +331,7 @@ Oit convz(It it, Oit oit)
300331{
301332 while (true )
302333 {
303- auto const cp = Utf::read (it, [] {});
334+ auto const cp = Utf::read (it, [] (It &) {});
304335 if (!cp)
305336 return oit;
306337 Outf::write (cp, oit);
@@ -324,14 +355,16 @@ template<
324355 typename Oit>
325356struct conv_strategy <Utf, Outf, It, Oit, false > final
326357{
327- static void func (It it, It const eit, Oit oit)
358+ Oit operator () (It it, It const eit, Oit oit)
328359 {
360+ auto const verify_fn = [&eit] (It & it)
361+ {
362+ if (it == eit)
363+ throw std::runtime_error (" Not enough input" );
364+ };
329365 while (it != eit)
330- Outf::write (Utf::read (it, [&it, &eit]
331- {
332- if (it == eit)
333- throw std::runtime_error (" Not enough input" );
334- }), oit);
366+ Outf::write (Utf::read (it, verify_fn), oit);
367+ return oit;
335368 }
336369};
337370
@@ -342,20 +375,22 @@ template<
342375 typename Oit>
343376struct conv_strategy <Utf, Outf, It, Oit, true > final
344377{
345- static void func (It it, It const eit, Oit oit)
378+ Oit operator () (It it, It const eit, Oit oit)
346379 {
347380 if (static_cast <size_t >(eit - it) >= Utf::max_supported_symbol_size)
348381 {
349382 auto const fast_eit = eit - Utf::max_supported_symbol_size;
350383 while (it < fast_eit)
351- Outf::write (Utf::read (it, [] {}), oit);
384+ Outf::write (Utf::read (it, [] (It &) {}), oit);
352385 }
386+ auto const verify_fn = [&eit] (It & it)
387+ {
388+ if (it == eit)
389+ throw std::runtime_error (" Not enough input" );
390+ };
353391 while (it != eit)
354- Outf::write (Utf::read (it, [&it, &eit]
355- {
356- if (it == eit)
357- throw std::runtime_error (" Not enough input" );
358- }), oit);
392+ Outf::write (Utf::read (it, verify_fn), oit);
393+ return oit;
359394 }
360395};
361396
@@ -369,12 +404,12 @@ template<
369404 bool is_random_access_iterator = std::is_base_of<
370405 std::random_access_iterator_tag,
371406 typename std::iterator_traits<typename std::decay<It>::type>::iterator_category>::value>
372- void conv (It && it, It && eit, Oit && oit)
407+ Oit conv (It && it, It && eit, Oit && oit)
373408{
374- detail::conv_strategy<Utf, Outf,
409+ return detail::conv_strategy<Utf, Outf,
375410 typename std::decay<It>::type,
376411 typename std::decay<Oit>::type,
377- is_random_access_iterator>:: func (
412+ is_random_access_iterator>() (
378413 std::forward<It>(it),
379414 std::forward<It>(eit),
380415 std::forward<Oit>(oit));
0 commit comments