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: Fri, 04 Feb 2022 23:53:04 -0800 Organization: A noiseless patient Spider Lines: 65 Message-ID: <865yptlpgf.fsf@linuxsc.com> References: <87k0easj5d.fsf@bsb.me.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="fd296145b453fec571e4c44d6840aea3"; logging-data="758"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19UrRH1qw2XRrmPAwPCOHk9Mj6Am2LY6gM=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:Ru/ebPqPGzlMgBGAzvGJ+P4fQTQ= sha1:vpdXotFzzrULwLipyaWnmrdThLM= Xref: csiph.com comp.lang.c++:82908 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; }