@@ -184,59 +184,75 @@ concept write_read_punned_constraints = (std::contiguous_iterator<Iter>&&sizeof(
184
184
namespace details
185
185
{
186
186
template <std::size_t buffer_size,bool punning=false ,typename T,typename Iter>
187
- inline constexpr Iter ibuf_read (T& ib,Iter begin,Iter end)
187
+ requires std::same_as<std::iter_value_t <Iter>,typename std::remove_cvref_t <T>::char_type>
188
+ inline constexpr Iter ibuf_read_cold (T& ib,Iter begin,Iter end)
188
189
{
189
- std::size_t const buffer_remain (ib.ibuffer .end -ib.ibuffer .curr );
190
-
191
190
std::size_t n (end-begin);
192
- if (buffer_remain<n) // cache miss
191
+ std::size_t const buffer_remain (ib.ibuffer .end -ib.ibuffer .curr );
192
+ if (ib.ibuffer .end ==nullptr )
193
193
{
194
- if (ib. ibuffer . end == nullptr )
194
+ if (buffer_size<=n )
195
195
{
196
- if (buffer_size<=n)
197
- {
198
- return read (ib.native_handle (),begin,end);
199
- }
200
- ib.ibuffer .init_space ();
201
- ib.ibuffer .curr =ib.ibuffer .end =ib.ibuffer .beg ;
196
+ return read (ib.native_handle (),begin,end);
202
197
}
203
- if constexpr (punning)
204
- {
205
- std::memcpy (begin,ib.ibuffer .curr ,buffer_remain);
206
- begin+=buffer_remain;
207
- }
208
- else
209
- begin=std::copy_n (ib.ibuffer .curr ,buffer_remain,begin);
210
- if (begin+buffer_size<end)
211
- {
198
+ ib.ibuffer .init_space ();
199
+ ib.ibuffer .curr =ib.ibuffer .end =ib.ibuffer .beg ;
200
+ }
201
+ if constexpr (punning)
202
+ {
203
+ std::memcpy (begin,ib.ibuffer .curr ,buffer_remain*sizeof (std::iter_value_t <Iter>));
204
+ begin+=buffer_remain;
205
+ }
206
+ else
207
+ begin=std::copy_n (ib.ibuffer .curr ,buffer_remain,begin);
208
+ if (begin+buffer_size<end)
209
+ {
212
210
// if constexpr(std::contiguous_iterator<Iter>)
213
- begin=read (ib.native_handle (),begin,end);
211
+ begin=read (ib.native_handle (),begin,end);
214
212
/* else
215
- {
216
-
217
- }*/
218
- if (begin!=end)
219
- {
220
- ib.ibuffer .end =ib.ibuffer .curr =ib.ibuffer .beg ;
221
- return begin;
222
- }
213
+ {
214
+
215
+ }*/
216
+ if (begin!=end)
217
+ {
218
+ ib.ibuffer .end =ib.ibuffer .curr =ib.ibuffer .beg ;
219
+ return begin;
223
220
}
224
- ib.ibuffer .end =read (ib.native_handle (),ib.ibuffer .beg ,ib.ibuffer .beg +buffer_size);
225
- ib.ibuffer .curr =ib.ibuffer .beg ;
226
- n=end-begin;
227
- std::size_t const sz (ib.ibuffer .end -ib.ibuffer .beg );
228
- if (sz<n)
229
- n=sz;
230
221
}
222
+ ib.ibuffer .end =read (ib.native_handle (),ib.ibuffer .beg ,ib.ibuffer .beg +buffer_size);
223
+ ib.ibuffer .curr =ib.ibuffer .beg ;
224
+ n=end-begin;
225
+ std::size_t const sz (ib.ibuffer .end -ib.ibuffer .beg );
226
+ if (sz<n)
227
+ n=sz;
228
+ if constexpr (punning)
229
+ {
230
+ std::memcpy (begin,ib.ibuffer .curr ,n*sizeof (std::iter_value_t <Iter>));
231
+ begin+=n;
232
+ }
233
+ else
234
+ begin=std::copy_n (ib.ibuffer .curr ,n,begin);
235
+ ib.ibuffer .curr +=n;
236
+ return begin;
237
+ }
238
+
239
+ template <std::size_t buffer_size,bool punning=false ,typename T,typename Iter>
240
+ requires std::same_as<std::iter_value_t <Iter>,typename std::remove_cvref_t <T>::char_type>
241
+ inline constexpr Iter ibuf_read (T& ib,Iter begin,Iter end)
242
+ {
243
+ std::size_t n (end-begin);
244
+ if (ib.ibuffer .curr +n<ib.ibuffer .end )[[unlikely]] // cache miss
245
+ return ibuf_read_cold<buffer_size,punning>(ib,begin,end);
231
246
if constexpr (punning)
232
247
{
233
- std::memcpy (begin,ib.ibuffer .curr ,n);
248
+ std::memcpy (begin,ib.ibuffer .curr ,n* sizeof (std:: iter_value_t <Iter>) );
234
249
begin+=n;
235
250
}
236
251
else
237
252
begin=std::copy_n (ib.ibuffer .curr ,n,begin);
238
253
ib.ibuffer .curr +=n;
239
254
return begin;
255
+
240
256
}
241
257
}
242
258
@@ -246,7 +262,12 @@ inline constexpr Iter read(basic_ibuf<Ihandler,Buf>& ib,Iter begin,Iter end)
246
262
{
247
263
using char_type = typename basic_ibuf<Ihandler,Buf>::char_type;
248
264
if constexpr (std::same_as<char_type,typename std::iterator_traits<Iter>::value_type>)
249
- return details::ibuf_read<Buf::size>(ib,begin,end);
265
+ {
266
+ if (std::is_constant_evaluated ())
267
+ return details::ibuf_read<Buf::size>(ib,std::to_address (begin),std::to_address (end));
268
+ else
269
+ return details::ibuf_read<Buf::size,true >(ib,std::to_address (begin),std::to_address (end));
270
+ }
250
271
else
251
272
{
252
273
auto b (reinterpret_cast <char const *>(std::to_address (begin)));
@@ -408,56 +429,65 @@ inline constexpr decltype(auto) ibuffer_set_curr(basic_obuf<Ohandler,Buf>& ob,ty
408
429
namespace details
409
430
{
410
431
411
- template <bool punning=false ,typename T,typename Iter>
412
- inline constexpr void obuf_write (T& ob,Iter cbegin,Iter cend)
432
+ template <bool punning=false ,typename T,std::contiguous_iterator Iter>
433
+ constexpr void obuf_write_cold (T& ob,Iter cbegin,Iter cend,std:: size_t diff )
413
434
{
414
- std::size_t const n (ob.obuffer .end -ob.obuffer .curr );
415
- std::size_t const diff (std::distance (cbegin,cend));
416
- if (n<diff)[[unlikely]]
435
+ if (ob.obuffer .end ==nullptr ) // cold buffer
417
436
{
418
- if (ob.obuffer .end ==nullptr ) // cold buffer
419
- {
420
- if (T::buffer_type::size<=diff)
421
- {
422
- write (ob.native_handle (),cbegin,cend);
423
- return ;
424
- }
425
- ob.obuffer .init_space ();
426
- ob.obuffer .end =(ob.obuffer .curr =ob.obuffer .beg )+T::buffer_type::size;
427
- if constexpr (punning)
428
- std::memcpy (ob.obuffer .curr ,cbegin,diff);
429
- else
430
- std::copy_n (cbegin,diff,ob.obuffer .curr );
431
- ob.obuffer .curr +=diff;
432
- return ;
433
- }
434
- /* if constexpr(punning)
435
- std::memcpy(ob.obuffer.curr,cbegin,n);
436
- else*/
437
- std::copy_n (cbegin,n,ob.obuffer .curr );
438
- cbegin+=n;
439
- write (ob.native_handle (),ob.obuffer .beg ,ob.obuffer .end );
440
- if (cbegin+(T::buffer_type::size)<cend)
437
+ if (T::buffer_type::size<=diff)
441
438
{
442
439
write (ob.native_handle (),cbegin,cend);
443
- ob. obuffer . curr =ob. obuffer . beg ;
440
+ return ;
444
441
}
442
+ ob.obuffer .init_space ();
443
+ ob.obuffer .end =(ob.obuffer .curr =ob.obuffer .beg )+T::buffer_type::size;
444
+ if constexpr (punning)
445
+ memcpy (ob.obuffer .curr ,cbegin,diff*sizeof (std::iter_value_t <Iter>));
445
446
else
446
- {
447
- std::size_t const df (cend-cbegin);
448
- if constexpr (punning)
449
- std::memcpy (ob.obuffer .beg ,cbegin,df);
450
- else
451
- std::copy_n (cbegin,df,ob.obuffer .beg );
452
- ob.obuffer .curr =ob.obuffer .beg +df;
453
- }
447
+ std::copy_n (cbegin,diff,ob.obuffer .curr );
448
+ ob.obuffer .curr +=diff;
454
449
return ;
455
450
}
451
+ std::size_t n (ob.obuffer .end -ob.obuffer .curr );
456
452
if constexpr (punning)
457
- std::memcpy (ob.obuffer .curr ,cbegin,diff);
453
+ memcpy (ob.obuffer .curr ,cbegin,n*sizeof (std::iter_value_t <Iter>));
454
+ else
455
+ std::copy_n (cbegin,n,ob.obuffer .curr );
456
+ cbegin+=n;
457
+ write (ob.native_handle (),ob.obuffer .beg ,ob.obuffer .end );
458
+ if (cbegin+(T::buffer_type::size)<cend)
459
+ {
460
+ write (ob.native_handle (),cbegin,cend);
461
+ ob.obuffer .curr =ob.obuffer .beg ;
462
+ }
458
463
else
459
- std::copy_n (cbegin,diff,ob.obuffer .curr );
460
- ob.obuffer .curr +=diff;
464
+ {
465
+ std::size_t const df (cend-cbegin);
466
+ if constexpr (punning)
467
+ memcpy (ob.obuffer .beg ,cbegin,df*sizeof (std::iter_value_t <Iter>));
468
+ else
469
+ std::copy_n (cbegin,df,ob.obuffer .beg );
470
+ ob.obuffer .curr =ob.obuffer .beg +df;
471
+ }
472
+ }
473
+
474
+ template <bool punning=false ,typename T,std::contiguous_iterator Iter>
475
+ requires std::same_as<std::iter_value_t <Iter>,typename std::remove_cvref_t <T>::char_type>
476
+ inline constexpr void obuf_write (T& ob,Iter cbegin,Iter cend)
477
+ {
478
+ std::size_t const diff (cend-cbegin);
479
+ auto curr{ob.obuffer .curr };
480
+ auto e{curr+diff};
481
+ if (e<ob.obuffer .end )[[likely]]
482
+ {
483
+ if constexpr (punning)
484
+ memcpy (curr,cbegin,diff*sizeof (std::iter_value_t <Iter>));
485
+ else
486
+ std::copy_n (cbegin,diff,ob.obuffer .curr );
487
+ ob.obuffer .curr =e;
488
+ return ;
489
+ }
490
+ obuf_write_cold<punning>(ob,cbegin,cend,diff);
461
491
}
462
492
463
493
}
@@ -468,7 +498,12 @@ inline constexpr void write(basic_obuf<Ohandler,Buf>& ob,Iter cbegini,Iter cendi
468
498
{
469
499
using char_type = typename basic_obuf<Ohandler,Buf>::char_type;
470
500
if constexpr (std::same_as<char_type,typename std::iterator_traits<Iter>::value_type>)
471
- details::obuf_write<false >(ob,std::to_address (cbegini),std::to_address (cendi));
501
+ {
502
+ if (std::is_constant_evaluated ())
503
+ details::obuf_write<false >(ob,std::to_address (cbegini),std::to_address (cendi));
504
+ else
505
+ details::obuf_write<true >(ob,std::to_address (cbegini),std::to_address (cendi));
506
+ }
472
507
else
473
508
details::obuf_write<true >(ob,reinterpret_cast <char const *>(std::to_address (cbegini)),
474
509
reinterpret_cast <char const *>(std::to_address (cendi)));
0 commit comments