Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c++ Subject: Re: C++20 concepts rocks Date: Sun, 06 Feb 2022 02:11:31 -0800 Organization: A noiseless patient Spider Lines: 83 Message-ID: <86wni8jodo.fsf@linuxsc.com> References: <87k0easj5d.fsf@bsb.me.uk> <865yptlpgf.fsf@linuxsc.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="a80c60510ddf69c3dc6a890da3a37a42"; logging-data="31089"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18qivzj6d8HvKZmOeaRzyW0kC9PTvRtvhw=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:vSKT/3Y5zEVCcLRy48I2o8K1gns= sha1:Vp8Itzc3ocGnluZXuBBAUQQXzGA= Xref: csiph.com comp.lang.c++:82931 red floyd writes: > On 2/4/2022 11:53 PM, Tim Rentsch wrote: > >> Ben Bacarisse writes: >> >>> Bonita Montero writes: >>> >>>> Am 04.02.2022 um 15:25 schrieb Muttley@dastardlyhq.com: >>>> >>>>> On Fri, 4 Feb 2022 13:54:27 +0100 >>>>> Bonita Montero wrote: >>>>> >>>>>> I've just written a small routine: >>>>>> >>>>>> [.. some c++ code ..] >>>>> >>>>> Thats nice. Personally I'd just use printf(). >>>> >>>> You can't do what I did with (s)printf(). >>> >>> template >>> requires is_same_v>> basic_string>> typename StringType::traits_type, >>> typename StringType::allocator_type>> >>> StringType formatClockCycles(uint64_t clockCycles) >>> { >>> char result[28], *ep = (&result)[1]; >>> do { >>> sprintf(ep - 4, "%03lu", clockCycles % 1000); >>> if (ep != (&result)[1]) ep[-1] = '.'; >>> ep -= 4; >>> } while (clockCycles /= 1000); >>> while (*ep == '0' && ep[1]) ep++; >>> return ep; >>> } >>> >>> (the appropriate comment on the 28 is left as an exercise to the reader!) >> >> Most of the work can be done using only a single call to sprintf(). >> (Disclaimer: not compiled.) >> >> >> template< typename StringType > >> requires >> is_same_v< >> StringType, >> basic_string< >> typename StringType::value_type, >> typename StringType::traits_type, >> typename StringType::allocator_type >> > >> > >> StringType >> formatClockCycles( uint64_t clockCycles ){ >> char result[ 27 ]; >> int n = sprintf( result, "%" PRIu64, clockCycles ); >> char *ep = (&result)[1]; >> >> *--ep = 0; >> while( n > 3 ){ >> memmove( ep -= 3, &result[ n -= 3 ], 3 ); >> *--ep = '.'; >> } >> do *--ep = result[ --n ]; while( n > 0 ); >> >> return ep; >> } > > Why the oddly unreadable initialization of ep? Because it was used in the posting to which I was responding. I simply copied it from there, not wanting to confuse matters with unnecessary changes. > Why not just > > char *ep = result + sizeof(result)? My usual practice is a somewhat different construction, suitably encapsulated so as not to sprinkle idiomatic phrases throughout the main program text.