Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #83760 > unrolled thread

"Performance of C++20's Ranges"

Started byCholo Lennon <chololennon@hotmail.com>
First post2022-04-26 01:13 -0300
Last post2022-04-27 18:35 +0200
Articles 20 on this page of 82 — 14 participants

Back to article view | Back to comp.lang.c++


Contents

  "Performance of C++20's Ranges" Cholo Lennon <chololennon@hotmail.com> - 2022-04-26 01:13 -0300
    Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-26 09:15 +0000
      Re: "Performance of C++20's Ranges" Juha Nieminen <nospam@thanks.invalid> - 2022-04-26 09:27 +0000
        Re: "Performance of C++20's Ranges" Manfred <noname@add.invalid> - 2022-04-26 16:29 +0200
          Re: "Performance of C++20's Ranges" "Ross A. Finlayson" <ross.finlayson@gmail.com> - 2022-05-01 18:45 -0700
      Re: "Performance of C++20's Ranges" "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-04-26 11:42 +0200
        Re: "Performance of C++20's Ranges" Juha Nieminen <nospam@thanks.invalid> - 2022-04-26 11:11 +0000
          Re: "Performance of C++20's Ranges" "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-04-26 13:31 +0200
          Re: "Performance of C++20's Ranges" Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-26 06:46 -0700
          Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-27 08:20 +0000
            Re: "Performance of C++20's Ranges" Juha Nieminen <nospam@thanks.invalid> - 2022-04-27 08:40 +0000
              Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-27 15:12 +0000
                Re: "Performance of C++20's Ranges" scott@slp53.sl.home (Scott Lurndal) - 2022-04-27 16:09 +0000
                  Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-27 16:21 +0000
                    Re: "Performance of C++20's Ranges" Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-29 16:15 -0700
                      Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-30 16:00 +0000
              Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-27 19:03 +0200
            Re: "Performance of C++20's Ranges" James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-27 11:12 -0400
              Re: "Performance of C++20's Ranges" Juha Nieminen <nospam@thanks.invalid> - 2022-04-28 06:45 +0000
        Re: "Performance of C++20's Ranges" Juha Nieminen <nospam@thanks.invalid> - 2022-04-27 06:30 +0000
          Re: "Performance of C++20's Ranges" Manfred <noname@add.invalid> - 2022-04-28 23:57 +0200
            Re: "Performance of C++20's Ranges" Juha Nieminen <nospam@thanks.invalid> - 2022-04-29 06:07 +0000
          Re: "Performance of C++20's Ranges" Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-29 16:28 -0700
            Re: "Performance of C++20's Ranges" Juha Nieminen <nospam@thanks.invalid> - 2022-05-02 05:01 +0000
              Re: "Performance of C++20's Ranges" Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-05-10 07:36 -0700
      Re: "Performance of C++20's Ranges" James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-26 11:28 -0400
        Re: "Performance of C++20's Ranges" Manfred <noname@add.invalid> - 2022-04-26 18:13 +0200
        Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-26 16:24 +0000
          Re: "Performance of C++20's Ranges" James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-26 12:48 -0400
      Re: "Performance of C++20's Ranges" Cholo Lennon <chololennon@hotmail.com> - 2022-04-26 20:20 -0300
        Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-27 08:30 +0000
          Re: "Performance of C++20's Ranges" Juha Nieminen <nospam@thanks.invalid> - 2022-04-27 08:50 +0000
            Re: "Performance of C++20's Ranges" Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-27 05:12 -0700
            Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-27 15:18 +0000
              Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-27 18:56 +0200
                Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 08:40 +0000
                  Re: "Performance of C++20's Ranges" Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-28 13:54 +0300
                    Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 13:11 +0200
                      Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 15:25 +0000
                        Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 17:30 +0200
                          Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 15:45 +0000
                            Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 17:52 +0200
                              Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 15:57 +0000
                                Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 18:01 +0200
                                  Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 16:06 +0000
                                    Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 18:09 +0200
                                      Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 16:14 +0000
                        Re: "Performance of C++20's Ranges" "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-04-28 16:11 -0700
                          Re: "Performance of C++20's Ranges" "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-04-28 16:20 -0700
                          Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-29 09:31 +0000
                    Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 15:15 +0000
                  Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 13:07 +0200
                    Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 15:17 +0000
                      Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 17:31 +0200
                        Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 15:50 +0000
                          Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 17:55 +0200
                            Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 15:59 +0000
                              Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 18:02 +0200
                                Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 16:13 +0000
                                  Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 18:20 +0200
                                    Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-29 09:27 +0000
                                      Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-29 20:48 +0200
                                      Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-30 07:34 +0200
                                        Re: "Performance of C++20's Ranges" scott@slp53.sl.home (Scott Lurndal) - 2022-04-30 17:31 +0000
                                          Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-30 20:30 +0200
                                          Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-05-01 15:20 +0000
                                            Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-05-01 18:18 +0200
                                              Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-05-01 16:25 +0000
                                            Re: "Performance of C++20's Ranges" scott@slp53.sl.home (Scott Lurndal) - 2022-05-01 23:14 +0000
                                Re: "Performance of C++20's Ranges" "Ross A. Finlayson" <ross.finlayson@gmail.com> - 2022-05-01 18:52 -0700
                              Re: "Performance of C++20's Ranges" scott@slp53.sl.home (Scott Lurndal) - 2022-04-28 18:21 +0000
                                Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-29 09:29 +0000
                            Re: "Performance of C++20's Ranges" scott@slp53.sl.home (Scott Lurndal) - 2022-04-28 18:19 +0000
                              Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-28 21:01 +0200
                      Re: "Performance of C++20's Ranges" "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-04-28 16:07 -0700
                    Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 15:22 +0000
              Re: "Performance of C++20's Ranges" Juha Nieminen <nospam@thanks.invalid> - 2022-04-28 10:57 +0000
                Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-28 15:27 +0000
                Re: "Performance of C++20's Ranges" red floyd <no.spam.here@its.invalid> - 2022-04-28 09:26 -0700
          Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-27 17:07 +0200
            Re: "Performance of C++20's Ranges" Muttley@dastardlyhq.com - 2022-04-27 15:54 +0000
              Re: "Performance of C++20's Ranges" Bonita Montero <Bonita.Montero@gmail.com> - 2022-04-27 18:35 +0200

Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →


#83860

FromManfred <noname@add.invalid>
Date2022-04-28 23:57 +0200
Message-ID<t4f2kn$13dg$1@gioia.aioe.org>
In reply to#83801
On 4/27/2022 8:30 AM, Juha Nieminen wrote:
> Alf P. Steinbach <alf.p.steinbach@gmail.com> wrote:
>> The Ranges library adds not just an new huge API but another large
>> domain specific language which results in very brittle code, and huge
>> complexity, that maintenance programmers must deal with.
> 
> Ok, let me put it this way:
> 
> The ranges library is just that: A library. It's not part of the language
> syntax itself. It's not making C++ "more complicated" because it's not
> changing the C++ language itself. It's simply an ancillary auxiliary
> library.
> 
> You treat these new standard libraries as if they made the language more
> complicated and complex because from now forward you will have to encounter
> C++ code that uses this library, meaning you will need to know what this
> library is doing if you want to undrestand that code.

But in fact they do make the language more complicated and complex, 
simply because they get into the standard, and make it fatter and heavier.
The argument about "if you don't want it you are free to ignore it" does 
not really apply once it gets into the standard, which means that these 
features start pouring into code, even if by misuse, just because they 
do become part of the language.

There are already examples of this: Java and .NET are are probably the 
most obvious ones. Them being so bloated should be reason enough to 
consider if it is really needed to make C++ as fat as the Vasa (TM)

> 
> What you aren't considering is this: How is that different from programs
> that use third-party libraries? There are very few C++ programs out there
> that don't use *any* third-party libraries. A few programs may get away
> with not using any (especially now that the standard library supports
> more than it did before, eg. <filesystem> and <thread>), but those are
> the minority. The larger the program, the more likely it's using some
> third-party library.

Third party libraries are substantially different: since they are not 
part of the language, they get through a selection process by the 
developer or the team, which ensure that their benefit pays for their 
cost, including the cost of added complexity.

> 
> That means that if you ever need to understand what the program is doing
> (eg. to maintain it), you'll need to study how that third-party library
> is used and how it works. (What's worse is that the "third-party library"
> might be completely unique, ie. having been created by the author of the
> program exclusively for that program, meaning there's zero chance you have
> ever encountered it before.)
> 
> How is that different from having to find out how, for example, the
> standard ranges library is used and how it works?
> 
> Well, I can tell you one big difference: Once you learn it you'll be able
> to understand a whole lot of more C++ programs out there, if and ostensibly
> when they start using it. With third-party libraries it's quite likely
> you have never even heard of it, so every time you encounter one you'll
> need to start learning from scratch.
> 
> Thus, there is quite a clear advantage in adding something to the standard
> library: The more programs start using it, the less learning you'll have
> to do in order to understand a C++ program.

[toc] | [prev] | [next] | [standalone]


#83868

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-04-29 06:07 +0000
Message-ID<t4fvba$971$1@gioia.aioe.org>
In reply to#83860
Manfred <noname@add.invalid> wrote:
>> What you aren't considering is this: How is that different from programs
>> that use third-party libraries? There are very few C++ programs out there
>> that don't use *any* third-party libraries. A few programs may get away
>> with not using any (especially now that the standard library supports
>> more than it did before, eg. <filesystem> and <thread>), but those are
>> the minority. The larger the program, the more likely it's using some
>> third-party library.
> 
> Third party libraries are substantially different: since they are not 
> part of the language, they get through a selection process by the 
> developer or the team, which ensure that their benefit pays for their 
> cost, including the cost of added complexity.

I don't think you understand the point I was making.

One of the most common complaints, also prominently presented in this thread,
is that when a library, like the ranges library, is added to the standard,
that means that people who need to maintain other people's code will start
encountering code that uses that library, meaning that it's yet again one
additional thing they need to study and learn and understand, even if it's
something they themselves never use.

But how exactly is this different from such a program using some third-party
library which, quite often, you have never used and thus need to study and
learn so that you can maintain the code that uses it? This is extremely
common, given how many millions of third-party libraries there are out there.

And, quite often, there are many different libraries for the same task,
and different programs will use different libraries. Thus often it's not
enough for you to learn one library for that particular task, and instead
you may encounter several of them.

A library being in the standard actually makes that better: The more
people use it, the less you will have to learn when maintaining their code.

[toc] | [prev] | [next] | [standalone]


#83889

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-04-29 16:28 -0700
Message-ID<86zgk34gg4.fsf@linuxsc.com>
In reply to#83801
Juha Nieminen <nospam@thanks.invalid> writes:

> Alf P. Steinbach <alf.p.steinbach@gmail.com> wrote:
>
>> The Ranges library adds not just an new huge API but another large
>> domain specific language which results in very brittle code, and
>> huge complexity, that maintenance programmers must deal with.
>
> Ok, let me put it this way:
>
> The ranges library is just that:  A library.  It's not part of the
> language syntax itself.  It's not making C++ "more complicated"
> because it's not changing the C++ language itself.  It's simply an
> ancillary auxiliary library.
>
> You treat these new standard libraries as if they made the language
> more complicated and complex because from now forward you will have
> to encounter C++ code that uses this library, meaning you will need
> to know what this library is doing if you want to undrestand that
> code.
>
> What you aren't considering is this:  How is that different from
> programs that use third-party libraries?  [...]

There are at least four differences between (in particular) ranges
and a third-party library.

One, there are some ranges-induced changes in the non-library
portion of the C++ standard.  Perhaps not very many, but some.
Third-party libraries don't do that.

Two, other areas of the library portion of the C++ standard are
affected by having ranges.  Third-party libraries don't do that.

Three, ranges are part of C++20, so using C++20 is a necessary
pre-requisite for using ranges.  Third-party libraries can be
compatible with, and usable in, earlier versions of C++.

Four, by virtue of being part of C++20, if someone wants to
use ranges then all the rest of C++20 comes along whether
they want it or not.  Third-party libraries can be (and
perhaps even often are) independent, so they can be used
(at least in many cases) without having to also take other
language changes (whether in the library or in the language
proper).

[toc] | [prev] | [next] | [standalone]


#83916

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-05-02 05:01 +0000
Message-ID<t4nok1$qv0$1@gioia.aioe.org>
In reply to#83889
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
> One, there are some ranges-induced changes in the non-library
> portion of the C++ standard.  Perhaps not very many, but some.

Such as?

> Two, other areas of the library portion of the C++ standard are
> affected by having ranges.  Third-party libraries don't do that.

So what?

> Three, ranges are part of C++20, so using C++20 is a necessary
> pre-requisite for using ranges.  Third-party libraries can be
> compatible with, and usable in, earlier versions of C++.

There are many third-party libraries that require C++11 and won't work
in C++98 code. There are many that require C++17. How is this different
from requiring C++20?

"Third party libraries can be compatible with" is a null sentence.
It isn't saying anything. Many third-party libraries could perhaps
be compatible with earlier versions of the language, but they aren't.
So what?

> Four, by virtue of being part of C++20, if someone wants to
> use ranges then all the rest of C++20 comes along whether
> they want it or not.  Third-party libraries can be (and
> perhaps even often are) independent, so they can be used
> (at least in many cases) without having to also take other
> language changes (whether in the library or in the language
> proper).

Again: There are many third-party libraries that require C++11 (and thus
"the rest of C++11 comes along whether they want it or not"). And so on.
So what? How is that different?

[toc] | [prev] | [next] | [standalone]


#84025

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-05-10 07:36 -0700
Message-ID<86ilqd4fpw.fsf@linuxsc.com>
In reply to#83916
Juha Nieminen <nospam@thanks.invalid> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
>

[some snipped context restored]

>> Juha Nieminen <nospam@thanks.invalid> writes:
>>
>>> The ranges library is just that:  A library.  It's not part of the
>>> language syntax itself.  It's not making C++ "more complicated"
>>> because it's not changing the C++ language itself.  It's simply an
>>> ancillary auxiliary library.
>>>
>>> You treat these new standard libraries as if they made the language
>>> more complicated and complex because from now forward you will have
>>> to encounter C++ code that uses this library, meaning you will need
>>> to know what this library is doing if you want to undrestand that
>>> code.
>>>
>>> What you aren't considering is this:  How is that different from
>>> programs that use third-party libraries?  [...]
>>
>> There are at least four differences between (in particular) ranges
>> and a third-party library.
>>
>> One, there are some ranges-induced changes in the non-library
>> portion of the C++ standard.  Perhaps not very many, but some.
>
> Such as?
>
>> Two, other areas of the library portion of the C++ standard are
>> affected by having ranges.  Third-party libraries don't do that.
>
> So what?
>
>> Three, ranges are part of C++20, so using C++20 is a necessary
>> pre-requisite for using ranges.  Third-party libraries can be
>> compatible with, and usable in, earlier versions of C++.
>
> There are many third-party libraries that require C++11 and won't
> work in C++98 code.  There are many that require C++17.  How is this
> different from requiring C++20?
>
> "Third party libraries can be compatible with" is a null sentence.
> It isn't saying anything.  Many third-party libraries could perhaps
> be compatible with earlier versions of the language, but they
> aren't.  So what?
>
>> Four, by virtue of being part of C++20, if someone wants to
>> use ranges then all the rest of C++20 comes along whether
>> they want it or not.  Third-party libraries can be (and
>> perhaps even often are) independent, so they can be used
>> (at least in many cases) without having to also take other
>> language changes (whether in the library or in the language
>> proper).
>
> Again:  There are many third-party libraries that require C++11
> (and thus "the rest of C++11 comes along whether they want it or
> not").  And so on.  So what?  How is that different?

You asked a question.  My response is an effort just to provide
a simple, factual answer.  Nothing more than that.

[toc] | [prev] | [next] | [standalone]


#83792

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-04-26 11:28 -0400
Message-ID<t49328$ugo$1@dont-email.me>
In reply to#83771
On 4/26/22 05:15, Muttley@dastardlyhq.com wrote:
> On Tue, 26 Apr 2022 01:13:41 -0300
...
> C++ used to be a svelt , clean language. Now its rapidly turning in Javas
> brother with new huge APIs that no one asked for being added such as this.

Nothing ever gets added to C++ unless somebody asks for it to be added,
and then convinces a sufficiently large number of the committee members
to agree that adding it is a good idea. What you really mean is that you
didn't ask for it. You might be right about it being a bad idea (I
haven't looked into it), but it is certainly not un-asked for.

[toc] | [prev] | [next] | [standalone]


#83796

FromManfred <noname@add.invalid>
Date2022-04-26 18:13 +0200
Message-ID<t495nj$vvg$1@gioia.aioe.org>
In reply to#83792
On 4/26/2022 5:28 PM, James Kuyper wrote:
> On 4/26/22 05:15, Muttley@dastardlyhq.com wrote:
>> On Tue, 26 Apr 2022 01:13:41 -0300
> ...
>> C++ used to be a svelt , clean language. Now its rapidly turning in Javas
>> brother with new huge APIs that no one asked for being added such as this.
> 
> Nothing ever gets added to C++ unless somebody asks for it to be added,
> and then convinces a sufficiently large number of the committee members
> to agree that adding it is a good idea. What you really mean is that you
> didn't ask for it. You might be right about it being a bad idea (I
> haven't looked into it), but it is certainly not un-asked for.

That is certainly true (it's called lobbying in some contexts).

The problem might be that some of the additions may have been asked for 
by some party that may be very influential, but whose priority may be 
something else than quality of the language per se. Such as placement in 
the development market, or strategic decisions in steering market trends.

In this perspective, meaning "no one" as "no developer" (or "no wide 
developer audience") could be justified.

[toc] | [prev] | [next] | [standalone]


#83797

FromMuttley@dastardlyhq.com
Date2022-04-26 16:24 +0000
Message-ID<t496cn$1aod$1@gioia.aioe.org>
In reply to#83792
On Tue, 26 Apr 2022 11:28:06 -0400
James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
>On 4/26/22 05:15, Muttley@dastardlyhq.com wrote:
>> On Tue, 26 Apr 2022 01:13:41 -0300
>....
>> C++ used to be a svelt , clean language. Now its rapidly turning in Javas
>> brother with new huge APIs that no one asked for being added such as this.
>
>Nothing ever gets added to C++ unless somebody asks for it to be added,

Who asked for ranges? Presumably the committee will have a list of contacts.
Or is it just another circle jerk?

[toc] | [prev] | [next] | [standalone]


#83798

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-04-26 12:48 -0400
Message-ID<t497p3$8up$1@dont-email.me>
In reply to#83797
On 4/26/22 12:24, Muttley@dastardlyhq.com wrote:
> On Tue, 26 Apr 2022 11:28:06 -0400
> James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
...
>> Nothing ever gets added to C++ unless somebody asks for it to be added,
>
> Who asked for ranges? Presumably the committee will have a list of
> contacts.

The initial proposal should be available on the committee's web site.
The hard part will be locating it. That proposal will indicate who the
authors are. I'm not sufficiently interested to search for it. If you
are, the committee's URL is
<http://www.open-std.org/jtc1/sc22/wg21/>
A relevant document is cited in the latest draft of the standard that I
have access to as "ISO/IEC TS 21425:2017 Programming Languages — C ++
Extensions for ranges,"
There's several documents with titles referring to "ranges" at
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/>, with
n4651.pdf seeming the most relevant. You might want to check earlier and
later years than 2017.

> Or is it just another circle jerk?

I was not familiar with that term. I just looked it up, and it doesn't
seem applicable.

[toc] | [prev] | [next] | [standalone]


#83799

FromCholo Lennon <chololennon@hotmail.com>
Date2022-04-26 20:20 -0300
Message-ID<t49un2$1ki9$1@gioia.aioe.org>
In reply to#83771
On 4/26/22 6:15 AM, Muttley@dastardlyhq.com wrote:
> On Tue, 26 Apr 2022 01:13:41 -0300
> Cholo Lennon <chololennon@hotmail.com> wrote:
>> Three Benchmarks of C++20 Ranges vs Standard Algorithms
>>
>> https://www.cppstories.com/2022/ranges-perf
> 
> C++ used to be a svelt , clean language. Now its rapidly turning in Javas
> brother with new huge APIs that no one asked for being added such as this.
> If learning an API is more effort than writing code to do the same thing
> yourself then the API should be binned.
> 

I had said it before in the forum, C++ is an awful monster (disclaimer: 
I started with it in 1990, and I am still using it at professional 
level). Right now I am really frustrated with the language direction, 
tons of new (complicated) things living together with the old ones, OMG! 
code bases are horrible. What is worse, no one masters the language 
anymore because no one has the time to spend on the complex and 
continuous update :-(

Java and Python are on the same path... they were very simple years ago, 
but nowadays... :-O

I was reading The Register today... look at this comment:
https://forums.theregister.com/forum/all/2022/04/26/hare_c_software/#c_4450256

-- 
Cholo Lennon
Bs.As.
ARG

[toc] | [prev] | [next] | [standalone]


#83803

FromMuttley@dastardlyhq.com
Date2022-04-27 08:30 +0000
Message-ID<t4auug$1mph$1@gioia.aioe.org>
In reply to#83799
On Tue, 26 Apr 2022 20:20:01 -0300
Cholo Lennon <chololennon@hotmail.com> wrote:
>On 4/26/22 6:15 AM, Muttley@dastardlyhq.com wrote:
>> On Tue, 26 Apr 2022 01:13:41 -0300
>> Cholo Lennon <chololennon@hotmail.com> wrote:
>>> Three Benchmarks of C++20 Ranges vs Standard Algorithms
>>>
>>> https://www.cppstories.com/2022/ranges-perf
>> 
>> C++ used to be a svelt , clean language. Now its rapidly turning in Javas
>> brother with new huge APIs that no one asked for being added such as this.
>> If learning an API is more effort than writing code to do the same thing
>> yourself then the API should be binned.
>> 
>
>I had said it before in the forum, C++ is an awful monster (disclaimer: 
>I started with it in 1990, and I am still using it at professional 
>level). Right now I am really frustrated with the language direction, 
>tons of new (complicated) things living together with the old ones, OMG! 
>code bases are horrible. What is worse, no one masters the language 
>anymore because no one has the time to spend on the complex and 
>continuous update :-(

Indeed. Endless pointless syntax changes and API additions that will only
ever be used by 0.0001% of the user base but have to be understood because
some idiot will try and use them in production code (and get it wrong) that
you'll have to fix. Been there, done that. Plus you can guarantee that in
a job interview some clown will try and demonstrate he's smarter than you and
ask you about some obscure dusty corner of the language that you've never used
and because no one person can learn the whole of C++ now there's a good chance
you won't know the answer.

There's a point at which functionality updates should be left to 3rd party
libraries, not be put into the core language. 

Frankly IMO even adding threads to C++ was idiotic because they're limited
to the lowest common denominator implementation (Windows) and hence don't
have critical functionality such as 3 level locking. Also if the language
supports threading, why not multi process too? Silly inconsistency.

>Java and Python are on the same path... they were very simple years ago, 
>but nowadays... :-O

I gave up on Java 10 years ago for that very reason.

>I was reading The Register today... look at this comment:
>https://forums.theregister.com/forum/all/2022/04/26/hare_c_software/#c_4450256

Spot on.

[toc] | [prev] | [next] | [standalone]


#83805

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-04-27 08:50 +0000
Message-ID<t4b04h$93a$1@gioia.aioe.org>
In reply to#83803
Muttley@dastardlyhq.com wrote:
> Indeed. Endless pointless syntax changes and API additions that will only
> ever be used by 0.0001% of the user base but have to be understood because
> some idiot will try and use them in production code (and get it wrong) that
> you'll have to fix.

You know, because the situation is so much better when programs use
third-party libraries (which the vast, vast majority of them do).
Because, as we all know, there doesn't exist any third-party library that
"will only ever be used bh 0.0001% of the user base but have to be understood
because some idiot will try and use them in production code".

Because, naturally, it's ok when it's a third-party library. But heaven
forbid it's a standard library! That's when everything goes wrong!
Nothing ever goes wrong with third-party libraries!

> Been there, done that. Plus you can guarantee that in
> a job interview some clown will try and demonstrate he's smarter than you and
> ask you about some obscure dusty corner of the language that you've never used
> and because no one person can learn the whole of C++ now there's a good chance
> you won't know the answer.

But when they ask "do you have experience with (some random third-party
library that's being extensively used in this particular company)?"
that's absolutely ok. As long as it's not a standard library everything
is fine.

> There's a point at which functionality updates should be left to 3rd party
> libraries, not be put into the core language. 

Indeed. As we all know, none of the problems mentioned in this thread ever
happen with third-party libraries. They are perfect! And we all know by
heart how to use all those libraries, and thus we never encounter any of
these problems with them, unlike the standard libraries which nobody knows
how to use.

You'll never encounter an unknown third-party library in some program you
need to maintain, which you then need to figure out and learn how it's used.
It's only if the program uses a standard library that you need to start
learning. Heaven forbid!

> Frankly IMO even adding threads to C++ was idiotic because they're limited
> to the lowest common denominator implementation (Windows) and hence don't
> have critical functionality such as 3 level locking.

Of course. If we want multithreading support in our programs, we have to
use non-portable platform-specific libraries. Heaven forbid we have a
standard way to do it! And what makes it worse is that if it's a standard
library you'll have to learn it in order to use it and fix code that
uses it, unlike all those third-party libraries that have no such
requirements! You are born with full understanding of those third-party
libraries!

If only the standardization committee understood these facts!

[toc] | [prev] | [next] | [standalone]


#83807

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2022-04-27 05:12 -0700
Message-ID<5df5219b-bf65-4ee2-b8ce-1d4c19761268n@googlegroups.com>
In reply to#83805
On Wednesday, 27 April 2022 at 09:50:42 UTC+1, Juha Nieminen wrote:
> Mut...@dastardlyhq.com wrote: 
> 
> > Been there, done that. Plus you can guarantee that in 
> > a job interview some clown will try and demonstrate he's smarter than you and 
> > ask you about some obscure dusty corner of the language that you've never used 
> > and because no one person can learn the whole of C++ now there's a good chance 
> > you won't know the answer.
> But when they ask "do you have experience with (some random third-party 
> library that's being extensively used in this particular company)?" 
> that's absolutely ok. As long as it's not a standard library everything 
> is fine.
>
With the third party library, the answer is either "yes" or "no".
Sometimes employers want to find someone who has worked on exactly the
same system that they are recruiting for. However that's pretty rare. Usually
they realise that this restricts the field of candidates very considerably, and
that the best candidate in other ways likely won't have the direct experience.

With a standard library, if you are a C++ programmer you've probably heard of
it, and written a few test routines to try it out. But quite likely you don't use
the feature in any serious way. That can be more damaging. If you say "no"
then the recruiter will say "but I'm looking for someone familiar with modern
C++". If you say "yes", the recruiter is within his rights to say "so can you 
write down a little routine which passes two ranges, one with all the odd
elements, one with all the even elements?". When you can't do it, after having
claimed familiarity, it looks really bad.

 

[toc] | [prev] | [next] | [standalone]


#83811

FromMuttley@dastardlyhq.com
Date2022-04-27 15:18 +0000
Message-ID<t4bmsk$1h8p$1@gioia.aioe.org>
In reply to#83805
On Wed, 27 Apr 2022 08:50:27 -0000 (UTC)
Juha Nieminen <nospam@thanks.invalid> wrote:
>Muttley@dastardlyhq.com wrote:
>> Indeed. Endless pointless syntax changes and API additions that will only
>> ever be used by 0.0001% of the user base but have to be understood because
>> some idiot will try and use them in production code (and get it wrong) that
>> you'll have to fix.
>
>You know, because the situation is so much better when programs use
>third-party libraries (which the vast, vast majority of them do).
>Because, as we all know, there doesn't exist any third-party library that
>"will only ever be used bh 0.0001% of the user base but have to be understood
>because some idiot will try and use them in production code".
>
>Because, naturally, it's ok when it's a third-party library. But heaven
>forbid it's a standard library! That's when everything goes wrong!
>Nothing ever goes wrong with third-party libraries!

Nothing to do with whether it goes wrong and all to do with whether they get
used in code or interviews.

>> Been there, done that. Plus you can guarantee that in
>> a job interview some clown will try and demonstrate he's smarter than you and
>
>> ask you about some obscure dusty corner of the language that you've never
>used
>> and because no one person can learn the whole of C++ now there's a good
>chance
>> you won't know the answer.
>
>But when they ask "do you have experience with (some random third-party
>library that's being extensively used in this particular company)?"
>that's absolutely ok. As long as it's not a standard library everything
>is fine.

If a company requires you to know Boost or Mongo-C it'll say so explicitely
in the job spec. When they say "C++20 desired" what does that mean? Which bit?
All of it? Who fucking knows!

>Indeed. As we all know, none of the problems mentioned in this thread ever
>happen with third-party libraries. They are perfect! And we all know by
>heart how to use all those libraries, and thus we never encounter any of
>these problems with them, unlike the standard libraries which nobody knows
>how to use.

You're repeating yourself.

>> Frankly IMO even adding threads to C++ was idiotic because they're limited
>> to the lowest common denominator implementation (Windows) and hence don't
>> have critical functionality such as 3 level locking.
>
>Of course. If we want multithreading support in our programs, we have to
>use non-portable platform-specific libraries. Heaven forbid we have a

If I need 3 level locking (which I do in most threaded programs) then its
pthreads for me because the simpleton C++ threading model doesn't support it.

>If only the standardization committee understood these facts!

Why haven't the committee implemented multi-process support in C++? Oh wait,
Windows multi-process model is a joke, thats why. Lowest common denominator
wins again.

[toc] | [prev] | [next] | [standalone]


#83817

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-04-27 18:56 +0200
Message-ID<t4bsig$g7t$1@dont-email.me>
In reply to#83811
> If I need 3 level locking (which I do in most threaded programs) then its
> pthreads for me because the simpleton C++ threading model doesn't support it.

What's "3 level locking" ? Description / URL ?

> Why haven't the committee implemented multi-process support in C++?
> Oh wait, Windows multi-process model is a joke, thats why. Lowest
> common denominator wins again.

Win32 kernel APIs are by far more elegant than this Posix- / SysV-
/ BSD-stuff. It's just the implementation that is rather slow.

[toc] | [prev] | [next] | [standalone]


#83829

FromMuttley@dastardlyhq.com
Date2022-04-28 08:40 +0000
Message-ID<t4djtj$kff$1@gioia.aioe.org>
In reply to#83817
On Wed, 27 Apr 2022 18:56:06 +0200
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>> If I need 3 level locking (which I do in most threaded programs) then its
>> pthreads for me because the simpleton C++ threading model doesn't support it.
>
>
>What's "3 level locking" ? Description / URL ?

You are kidding me, right? You spout off about threading all the time and 
you don't know the fundamentals? Educate yourself:

https://www.ibm.com/docs/en/aix/7.2?topic=programming-using-readwrite-locks

>> Why haven't the committee implemented multi-process support in C++?
>> Oh wait, Windows multi-process model is a joke, thats why. Lowest
>> common denominator wins again.
>
>Win32 kernel APIs are by far more elegant than this Posix- / SysV-
>/ BSD-stuff. It's just the implementation that is rather slow.

Sure. Remind me, whats the win32 equivalent of fork() again?

[toc] | [prev] | [next] | [standalone]


#83832

FromPaavo Helde <eesnimi@osa.pri.ee>
Date2022-04-28 13:54 +0300
Message-ID<t4drov$ld7$1@dont-email.me>
In reply to#83829
28.04.2022 11:40 Muttley@dastardlyhq.com kirjutas:
> On Wed, 27 Apr 2022 18:56:06 +0200
> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> If I need 3 level locking (which I do in most threaded programs) then its
>>> pthreads for me because the simpleton C++ threading model doesn't support it.
>>
>>
>> What's "3 level locking" ? Description / URL ?
> 
> You are kidding me, right? You spout off about threading all the time and
> you don't know the fundamentals? Educate yourself:
> 
> https://www.ibm.com/docs/en/aix/7.2?topic=programming-using-readwrite-locks

And read-write locks have been in C++ standard since 2017:

https://en.cppreference.com/w/cpp/thread/shared_mutex

[toc] | [prev] | [next] | [standalone]


#83835

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-04-28 13:11 +0200
Message-ID<t4dsot$78j$1@dont-email.me>
In reply to#83832
Am 28.04.2022 um 12:54 schrieb Paavo Helde:
> 28.04.2022 11:40 Muttley@dastardlyhq.com kirjutas:
>> On Wed, 27 Apr 2022 18:56:06 +0200
>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> If I need 3 level locking (which I do in most threaded programs) 
>>>> then its
>>>> pthreads for me because the simpleton C++ threading model doesn't 
>>>> support it.
>>>
>>>
>>> What's "3 level locking" ? Description / URL ?
>>
>> You are kidding me, right? You spout off about threading all the time and
>> you don't know the fundamentals? Educate yourself:
>>
>> https://www.ibm.com/docs/en/aix/7.2?topic=programming-using-readwrite-locks 
>>
> 
> And read-write locks have been in C++ standard since 2017:
> https://en.cppreference.com/w/cpp/thread/shared_mutex

This kind of shared lock is almost useless since it gives
readers priority over writers so that the writer can proceed
only if all readers have relinquished ownership. With my
shared lock, all further readers are enqueued when a writer
wants to gain ownership and the lock lets proceed the preceding
readers.

Here's the code:

// wbias_shared_mutex.h

#pragma once
#include <cstdint>
#include <cassert>
#include <thread>
#include <new>
#include <atomic>
#include <stdexcept>
#include <exception>
#include <limits>
#include <cstdint>
#include <semaphore>
#include "thread_id.h"
#include "msvc-disabler.h"

#if defined(__llvm__)
	#pragma clang diagnostic push
	#pragma clang diagnostic ignored "-Wdangling-else"
#endif

struct wbsm_exception : public std::exception
{
	enum reason : std::uint8_t
	{
		SHARER_COUNTER_SATURATED = 1,
		WATING_EXCLUSIVE_COUNTER_SATURATED = 2,
		RECURSION_COUNTER_SATURATED = 3
	};
	wbsm_exception() = delete;
	wbsm_exception( reason r, char const *what );
	reason get_reason();
	virtual
	char const *what() const noexcept;
private:
	reason m_reason;
	char const *m_what;
};

inline
wbsm_exception::wbsm_exception( reason r, char const *what ) :
	m_reason( r ),
	m_what( what )
{
}

inline
wbsm_exception::reason wbsm_exception::get_reason()
{
	return m_reason;
}

static_assert(std::atomic<std::uint64_t>::is_always_lock_free, 
"std::uint64_t must be lock-free");

struct alignas(64)
	wbias_shared_mutex
{
	wbias_shared_mutex( std::int16_t maxExclusiveSpinCount = 100, 
std::int16_t maxSharedSpinCount = 100 );
	wbias_shared_mutex( wbias_shared_mutex const & ) = delete;
	void operator =( wbias_shared_mutex const & ) = delete;
	~wbias_shared_mutex();
	void lock_shared();
	bool try_lock_shared();
	void unlock_shared();
	void shared_to_exclusive( thread_id const &threadId = thread_id::self() );
	void lock_exclusive( thread_id const &threadId = thread_id::self() );
	bool try_lock_exclusive( thread_id const &threadId = thread_id::self() );
	bool lock_preferred_shared( thread_id const &threadId = 
thread_id::self() );
	void unlock_exclusive( thread_id const &threadId = thread_id::self() );
	void exclusive_to_shared( bool force = false );
	bool is_shared();
	bool is_exclusive();
	bool we_are_exclusive( thread_id const &threadId = thread_id::self() );
	thread_id get_exclusive_thread_id();
	std::uint32_t get_exclusive_recursion_count();
	std::int16_t max_exclusive_spin_count( std::int16_t max );
	std::int16_t max_shared_spin_count( std::int16_t max );
private:
	static_assert(std::atomic<std::uint64_t>::is_always_lock_free, 
"std::atomic<std::uint64_t> must be always lock-free");
	std::atomic<std::uint64_t> m_atomic;
	thread_id m_exclusiveId;
	std::uint32_t m_exclusiveRecursionCount;
	std::int16_t m_exclusiveSpinCount, m_sharedSpinCount; // adaptive 
spinning taken from glibc
	std::int16_t m_maxExclusiveSpinCount, m_maxSharedSpinCount;
	std::counting_semaphore<((unsigned)-1 >> 1)> m_releaseSharedSem;
	std::binary_semaphore m_releaseExclusiveSem;

	static unsigned const WAITING_SHARERS_BASE = 21, WAITING_EXCLUSIVE_BASE 
= 42, EXCLUSIVE_FLAG_BASE = 63;
	static std::uint64_t const MASK21 = 0x1FFFFFu;
	static std::uint64_t const SHARERS_MASK = MASK21, WAITING_SHARERS_MASK 
= MASK21 << WAITING_SHARERS_BASE, WAITING_EXCLUSIVE_MASK = MASK21 << 
WAITING_EXCLUSIVE_BASE, EXCLUSIVE_FLAG_MASK = (std::uint64_t)1 << 
EXCLUSIVE_FLAG_BASE;
	static std::uint64_t const SHARER_VALUE = (std::uint64_t)1, 
WAITING_SHARERS_VALUE = (std::uint64_t)1 << WAITING_SHARERS_BASE, 
WAITING_EXCLUSIVE_VALUE = (std::uint64_t)1 << WAITING_EXCLUSIVE_BASE;
	static short const DEFAULT_MAX_SPIN_COUNT = 100;
#if !defined(NDEBUG)
	static bool check( std::uint64_t flags );
#endif
	bool internal_spin_lock_shared( std::uint64_t &cmp );
	void internal_lock_shared( uint64_t cmp );
	bool internal_spin_lock_exclusive( std::uint64_t &cmp, thread_id const 
&threadId );
	void cpu_pause();
};

inline
bool wbias_shared_mutex::is_shared()
{
	return m_atomic.load( std::memory_order_relaxed ) & SHARERS_MASK;
}

inline
bool wbias_shared_mutex::is_exclusive()
{
	return m_atomic.load( std::memory_order_relaxed ) & EXCLUSIVE_FLAG_MASK;
}

inline
bool wbias_shared_mutex::we_are_exclusive( thread_id const &threadId )
{
	return (m_atomic.load( std::memory_order_relaxed ) & 
EXCLUSIVE_FLAG_MASK) && m_exclusiveId == threadId;
}

inline
thread_id wbias_shared_mutex::get_exclusive_thread_id()
{
	//std::atomic_thread_fence( std::memory_order_acquire );
	return m_exclusiveId;
}

inline
std::uint32_t wbias_shared_mutex::get_exclusive_recursion_count()
{
	return m_exclusiveRecursionCount;
}


struct wbsm_lock
{
	enum : std::uint8_t
	{
		UNLOCKED,
		SHARED,
		EXLUSIVE
	};
	wbsm_lock();
	wbsm_lock( wbsm_lock const &other );
	wbsm_lock( wbsm_lock &&other ) noexcept;
	wbsm_lock( wbias_shared_mutex &mtx, bool lockShared = true, thread_id 
const &threadId = thread_id::self() );
	~wbsm_lock();
	wbsm_lock &operator =( wbsm_lock const &other );
	wbsm_lock &operator =( wbsm_lock &&other ) noexcept;
	void lock_shared( wbias_shared_mutex &mtx );
	void shared_to_exclusive( thread_id const &threadId = thread_id::self() );
	void exclusive_to_shared( bool force = false );
	void lock_exclusive( wbias_shared_mutex &mtx, thread_id const &threadId 
= thread_id::self() );
	void unlock();
	void lock_preferred_shared( wbias_shared_mutex &mtx, thread_id const 
&threadId = thread_id::self() );
	bool is_locked() const;
	bool is_shared() const;
	bool is_exclusive() const;
	thread_id get_exclusive_thread_id() const;
	wbias_shared_mutex *get_mutex() const;
	std::uint8_t get_state() const;
	void set_state( std::uint8_t state, wbias_shared_mutex &mtx );
private:
	wbias_shared_mutex *m_mtx;
	bool m_isShared;
	thread_id m_threadId;
};

inline
wbsm_lock::wbsm_lock()
{
	m_mtx = nullptr;
}

// may throw wbsm_exception if mutex-counter saturates

inline
wbsm_lock::wbsm_lock( wbsm_lock const &other ) :
	m_mtx( other.m_mtx ),
	m_isShared( other.m_isShared )
{
	if( m_isShared )
		m_mtx->lock_shared();
	else
		m_mtx->lock_exclusive( other.m_threadId ),
		m_threadId = m_mtx->get_exclusive_thread_id();
}

inline
wbsm_lock::wbsm_lock( wbsm_lock &&other ) noexcept :
	m_mtx( other.m_mtx ),
	m_isShared( other.m_isShared ),
	m_threadId( other.m_threadId )
{
	other.m_mtx = nullptr;
#if !defined(NDEBUG)
	other.m_threadId = thread_id();
#endif
}

// may throw wbsm_exception if mutex-counter saturates

inline
wbsm_lock::wbsm_lock( wbias_shared_mutex &mtx, bool lockShared, 
thread_id const &threadId )
{
	if( lockShared ) // [[likely]]
		mtx.lock_shared();
	else
		mtx.lock_exclusive( threadId ),
		m_threadId = mtx.get_exclusive_thread_id();
	m_mtx = &mtx;
	m_isShared = lockShared;
}

inline
wbsm_lock::~wbsm_lock()
{
	if( !m_mtx )
		return;
	if( m_isShared ) [[likely]]
		m_mtx->unlock_shared();
	else
		m_mtx->unlock_exclusive( m_threadId );
}

// may throw wbsm_exception if mutex-counter saturates

inline
wbsm_lock &wbsm_lock::operator =( wbsm_lock const &other )
{
	if( m_mtx == other.m_mtx )
		return *this;
	unlock();
	if( !other.m_mtx ) [[unlikely]]
		return *this;
	if( other.m_isShared )
		other.m_mtx->lock_shared();
	else
		other.m_mtx->lock_exclusive( other.m_threadId ),
		m_threadId = other.m_threadId;
	m_mtx = other.m_mtx;
	m_isShared = other.m_isShared;
	return *this;
}

inline
wbsm_lock &wbsm_lock::operator =( wbsm_lock &&other ) noexcept
{
	if( m_mtx == other.m_mtx )
	{
		other.unlock();
		return *this;
	}
	unlock();
	m_mtx = other.m_mtx;
	m_isShared = other.m_isShared;
	m_threadId = other.m_threadId;
	other.m_mtx = nullptr;
#if !defined(NDEBUG)
	other.m_threadId = thread_id();
#endif
	return *this;
}

// may throw wbsm_exception if mutex-counter saturates

inline
void wbsm_lock::lock_shared( wbias_shared_mutex &mtx )
{
	if( m_mtx == &mtx )
		if( m_isShared ) [[likely]]
			return;
		else
		{
			m_mtx->exclusive_to_shared();
			m_isShared = true;
#if !defined(NDEBUG)
			m_threadId = thread_id();
#endif
			return;
		}
	unlock();
	mtx.lock_shared();
	m_mtx = &mtx;
	m_isShared = true;
#if !defined(NDEBUG)
	m_threadId = thread_id();
#endif
}

// may throw wbsm_exception if mutex-counter saturates

inline
void wbsm_lock::shared_to_exclusive( thread_id const &threadId )
{
	assert(m_mtx);
	if( m_isShared )
		m_mtx->shared_to_exclusive( threadId ),
		m_isShared = false;
	m_threadId = threadId;
}

// may throw wbsm_exception if mutex-counter saturates

inline
void wbsm_lock::exclusive_to_shared( bool force )
{
	assert(m_mtx);
	if( m_isShared )
		return;
	m_mtx->exclusive_to_shared( force );
	m_isShared = true;
#if !defined(NDEBUG)
	m_threadId = thread_id();
#endif
}

// may throw wbsm_exception if mutex-counter saturates

inline
void wbsm_lock::lock_exclusive( wbias_shared_mutex &mtx, thread_id const 
&threadId )
{
	if( m_mtx == &mtx )
		if( !m_isShared )
			return;
		else
		{
			m_mtx->shared_to_exclusive( threadId );
			m_isShared = false;
			m_threadId = threadId;
			return;
		}
	unlock();
	mtx.lock_exclusive( threadId );
	m_mtx = &mtx;
	m_isShared = false;
	m_threadId = threadId;
}

inline
void wbsm_lock::unlock()
{
	if( !m_mtx ) [[unlikely]]
		return;
	if( m_isShared ) [[likely]]
		m_mtx->unlock_shared();
	else
		m_mtx->unlock_exclusive( m_threadId );
	m_mtx = nullptr;
}

// may throw wbsm_exception if mutex-counter saturates

inline
void wbsm_lock::lock_preferred_shared( wbias_shared_mutex &mtx, 
thread_id const &threadId )
{
	if( m_mtx != &mtx )
		m_isShared = mtx.lock_preferred_shared( threadId ),
		m_mtx = &mtx;
	m_threadId = threadId;
}

inline
bool wbsm_lock::is_locked() const
{
	return m_mtx != nullptr;
}

inline
bool wbsm_lock::is_shared() const
{
	assert(m_mtx);
	return m_isShared;
}

inline
bool wbsm_lock::is_exclusive() const
{
	assert(m_mtx);
	return !m_isShared;
}

inline
thread_id wbsm_lock::get_exclusive_thread_id() const
{
	return m_threadId;
}

inline
std::uint8_t wbsm_lock::get_state() const
{
	if( !m_mtx ) [[unlikely]]
		return wbsm_lock::UNLOCKED;
	if( m_isShared ) [[likely]]
		return wbsm_lock::SHARED;
	else		
		return wbsm_lock::EXLUSIVE;
}

inline
wbias_shared_mutex *wbsm_lock::get_mutex() const
{
	return m_mtx;
}

#if defined(__llvm__)
	#pragma clang diagnostic pop
#endif

// wbias_shared_mutex.cpp

#include <utility>
#include "wbias_shared_mutex.h"
#include "xassert.h"
#include "exc_encapsulate.h"
#if defined(_MSC_VER)
	#include <intrin.h>
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
	#include <immintrin.h>
#endif
#if defined(__llvm__)
	#pragma clang diagnostic push
	#pragma clang diagnostic ignored "-Wdangling-else"
#endif

char const *wbsm_exception::what() const noexcept
{
	return m_what;
}

#if !defined(NDEBUG)
inline
bool wbias_shared_mutex::check( std::uint64_t flags )
{
	unsigned
		sharers = (unsigned)(flags & MASK21),
		waitingExclusive = (unsigned)((flags >> WAITING_EXCLUSIVE_BASE) & MASK21),
		exclusiveFlag = (unsigned)((flags >> EXCLUSIVE_FLAG_BASE) & 1);
	if( sharers && exclusiveFlag )
		return false;
	if( waitingExclusive && !exclusiveFlag && !sharers )
		return false;
	return true;
}
#endif

wbias_shared_mutex::wbias_shared_mutex( std::int16_t 
maxExclusiveSpinCount, std::int16_t maxSharedSpinCount ) :
	m_atomic( 0 ),
	m_exclusiveId(),
	m_exclusiveSpinCount( 0 ),
	m_sharedSpinCount( 0 ),
	m_maxExclusiveSpinCount( maxExclusiveSpinCount ),
	m_maxSharedSpinCount( maxSharedSpinCount ),
	m_releaseSharedSem( 0 ),
	m_releaseExclusiveSem( 0 )
{
}

wbias_shared_mutex::~wbias_shared_mutex()
{
	assert(m_atomic == 0);
}

// throws wbsm_exception if waiting sharers counter saturates

void wbias_shared_mutex::lock_shared()
{
	using namespace std;
	uint64_t cmp = m_atomic.load( memory_order_relaxed );
	if( internal_spin_lock_shared( cmp ) )
		return;
	internal_lock_shared( cmp );
}

inline
bool wbias_shared_mutex::internal_spin_lock_shared( std::uint64_t &cmp )
{
	using namespace std;
	if( m_maxSharedSpinCount <= 0 )
		return false;
	int32_t maxSpin = (int32_t)m_sharedSpinCount * 2 + 10;
	maxSpin = maxSpin <= m_maxSharedSpinCount ? maxSpin : m_maxSharedSpinCount;
	int32_t spinCount = 0;
	bool locked = false;
	for( ; ; )
	{
		assert(check( cmp ));
		if( cmp & EXCLUSIVE_FLAG_MASK )
		{
			cpu_pause();
			cmp = m_atomic.load( memory_order_relaxed );
			continue;
		}
		if( (cmp & SHARERS_MASK) == SHARERS_MASK )
			return false;
		if( m_atomic.compare_exchange_weak( cmp, cmp + SHARER_VALUE, 
memory_order_acquire, memory_order_relaxed ) )
		{
			locked = true;
			break;
		}
		if( ++spinCount >= maxSpin )
			break;
		cpu_pause();
	}
	m_sharedSpinCount += ((int16_t)spinCount - m_sharedSpinCount) / 8;
	return locked;
}

// throws wbsm_exception if waiting sharers counter saturates

inline
void wbias_shared_mutex::internal_lock_shared( uint64_t cmp )
{
	using namespace std;
	for( ; ; )
	{
		assert(check( cmp ));
		if( (cmp & (EXCLUSIVE_FLAG_MASK | WAITING_EXCLUSIVE_MASK)) == 0 )
		{
			if( (cmp & SHARERS_MASK) == SHARERS_MASK )
				throw wbsm_exception( wbsm_exception::SHARER_COUNTER_SATURATED, 
"wbsm-lock sharer-counter saturated" );
			if( m_atomic.compare_exchange_weak( cmp, cmp + SHARER_VALUE, 
memory_order_acquire, memory_order_relaxed ) )
				return;
		}
		else
		{
			if( (cmp & SHARERS_MASK) + ((cmp & WAITING_SHARERS_MASK) >> 
WAITING_SHARERS_BASE) >= SHARERS_MASK )
				throw wbsm_exception( wbsm_exception::SHARER_COUNTER_SATURATED, 
"wbsm-lock sharer-counter saturated" );
			if( m_atomic.compare_exchange_weak( cmp, cmp + WAITING_SHARERS_VALUE, 
memory_order_relaxed, memory_order_relaxed ) )
			{
				exc_terminate_or_spin( [&]() { m_releaseSharedSem.acquire(); } );
				return;
			}
		}
	}
}

// throws wbsm_exception if recursion-counter saturates

inline
bool wbias_shared_mutex::internal_spin_lock_exclusive( std::uint64_t 
&cmp, thread_id const &threadId )
{
	using namespace std;
	assert(check( cmp ));
	if( (cmp & EXCLUSIVE_FLAG_MASK) && m_exclusiveId == threadId )
	{
		if( m_exclusiveRecursionCount == numeric_limits<uint32_t>::max() )
			throw wbsm_exception( wbsm_exception::RECURSION_COUNTER_SATURATED, 
"wbsm-lock recursion-counter saturated" );
		++m_exclusiveRecursionCount;
		return true;
	}
	if( m_maxExclusiveSpinCount <= 0 )
		return false;
	int32_t maxSpin = (int32_t)m_exclusiveSpinCount * 2 + 10;
	maxSpin = maxSpin <= m_maxExclusiveSpinCount ? maxSpin : 
m_maxExclusiveSpinCount;
	int32_t spinCount = 0;
	bool locked = false;
	for( ; ; )
	{
		assert(check( cmp ));
		cmp = 0;
		if( m_atomic.compare_exchange_weak( cmp, EXCLUSIVE_FLAG_MASK, 
memory_order_acquire, memory_order_relaxed ) )
		{
			m_exclusiveId = threadId;
			m_exclusiveRecursionCount = 0;
			locked = true;
			break;
		}
		if( ++spinCount >= maxSpin )
			break;
		cpu_pause();
	}
	m_exclusiveSpinCount += ((int16_t)spinCount - m_exclusiveSpinCount) / 8;
	return locked;
}

bool wbias_shared_mutex::try_lock_shared()
{
	using namespace std;
	uint64_t cmp = m_atomic.load( memory_order_relaxed );
	return internal_spin_lock_shared( cmp );
}

void wbias_shared_mutex::unlock_shared()
{
	using namespace std;
	for( uint64_t cmp = m_atomic.load( memory_order_relaxed ); ; )
	{
		assert(check( cmp ));
		assert((cmp & SHARERS_MASK) >= SHARER_VALUE);
		if( (cmp & WAITING_EXCLUSIVE_MASK) == 0 || (cmp & SHARERS_MASK) != 
SHARER_VALUE )
		{
			if( m_atomic.compare_exchange_weak( cmp, cmp - SHARER_VALUE, 
memory_order_relaxed, memory_order_relaxed ) )
				return;
		}
		else
		{
			assert(!(cmp & EXCLUSIVE_FLAG_MASK));
			if( m_atomic.compare_exchange_weak( cmp, (cmp - SHARER_VALUE - 
WAITING_EXCLUSIVE_VALUE) | EXCLUSIVE_FLAG_MASK, memory_order_relaxed, 
memory_order_relaxed ) )
			{
				exc_terminate_or_spin( [&]() { m_releaseExclusiveSem.release( 1 ); } );
				return;
			}
		}
	}
}

// throws wbsm_exception if waiting exclusive counter saturates

void wbias_shared_mutex::shared_to_exclusive( thread_id const &threadId )
{
	using namespace std;
	uint64_t cmp = m_atomic.load( memory_order_relaxed );
	if( m_maxExclusiveSpinCount > 0 )
	{
		int32_t maxSpin = (int32_t)m_exclusiveSpinCount * 2 + 10;
		maxSpin = maxSpin <= m_maxExclusiveSpinCount ? maxSpin : 
m_maxExclusiveSpinCount;
		int32_t spinCount = 0;
		bool locked = false;
		for( ; ; )
		{
			assert(check( cmp ));
			assert((cmp & SHARERS_MASK) >= SHARER_VALUE);
			cmp = (cmp & ~SHARERS_MASK) | 1;
			if( m_atomic.compare_exchange_weak( cmp, (cmp & ~SHARERS_MASK) | 
EXCLUSIVE_FLAG_MASK, memory_order_acquire, memory_order_relaxed ) )
			{
				m_exclusiveId = threadId;
				m_exclusiveRecursionCount = 0;
				locked = true;
				break;
			}
			if( ++spinCount >= maxSpin )
				break;
			cpu_pause();
		}
		m_exclusiveSpinCount += ((int16_t)spinCount - m_exclusiveSpinCount) / 8;
		if( locked )
			return;
	}
	for( ; ; )
	{
		assert(check( cmp ));
		assert((cmp & SHARERS_MASK) >= SHARER_VALUE);
		if( (cmp & SHARERS_MASK) == SHARER_VALUE )
			if( m_atomic.compare_exchange_weak( cmp, (cmp - SHARER_VALUE) | 
EXCLUSIVE_FLAG_MASK, memory_order_acquire, memory_order_relaxed ) )
			{
				m_exclusiveId = threadId;
				m_exclusiveRecursionCount = 0;
				return;
			}
			else;
		else
		{
			if( (cmp & WAITING_EXCLUSIVE_MASK) == WAITING_EXCLUSIVE_MASK )
				throw wbsm_exception( 
wbsm_exception::WATING_EXCLUSIVE_COUNTER_SATURATED, "wbsm-lock 
waiting-exclusive-count saturated" );
			if( m_atomic.compare_exchange_weak( cmp, cmp - SHARER_VALUE + 
WAITING_EXCLUSIVE_VALUE, memory_order_relaxed, memory_order_relaxed ) )
			{
				exc_terminate_or_spin( [&]() { m_releaseExclusiveSem.acquire(); } );
				m_exclusiveId = threadId;
				m_exclusiveRecursionCount = 0;
				return;
			}
		}
	}
}

// throws wbsm_exception if waiting exclusive counter saturates

void wbias_shared_mutex::lock_exclusive( thread_id const &threadId )
{
	using namespace std;
	uint64_t cmp = m_atomic.load( memory_order_acquire );
	if( internal_spin_lock_exclusive( cmp, threadId ) )
		return;
	for( ; ; )
	{
		assert(check( cmp ));
		if( (cmp & (EXCLUSIVE_FLAG_MASK | SHARERS_MASK)) == 0 )
		{
			if( m_atomic.compare_exchange_weak( cmp, cmp | EXCLUSIVE_FLAG_MASK, 
memory_order_acquire, memory_order_relaxed ) )
			{
				m_exclusiveId = threadId;
				m_exclusiveRecursionCount = 0;
				return;
			}
		}
		else
		{
			if( (cmp & WAITING_EXCLUSIVE_MASK) == WAITING_EXCLUSIVE_MASK )
				throw wbsm_exception( 
wbsm_exception::WATING_EXCLUSIVE_COUNTER_SATURATED, "wbsm-lock 
waiting-waiters-counter saturated" );
			if( m_atomic.compare_exchange_weak( cmp, cmp + 
WAITING_EXCLUSIVE_VALUE, memory_order_relaxed, memory_order_relaxed ) )
			{
				exc_terminate_or_spin( [&]() { m_releaseExclusiveSem.acquire(); } );
				m_exclusiveId = threadId;
				m_exclusiveRecursionCount = 0;
				return;
			}
		}
	}
}

bool wbias_shared_mutex::try_lock_exclusive( thread_id const &threadId )
{
	using namespace std;
	uint64_t cmp = m_atomic.load( memory_order_acquire );
	return internal_spin_lock_exclusive( cmp, threadId );
}

// throws wbsm_exception if recursion-counter saturates
// throws wbsm_exception if waiting sharers counter saturates

bool wbias_shared_mutex::lock_preferred_shared( thread_id const &threadId )
{
	using namespace std;
	uint64_t cmp = m_atomic.load( memory_order_acquire );
	assert(check( cmp ));
	if( (cmp & EXCLUSIVE_FLAG_MASK) && m_exclusiveId == threadId )
	{
		if( m_exclusiveRecursionCount == numeric_limits<uint32_t>::max() )
			throw wbsm_exception( wbsm_exception::RECURSION_COUNTER_SATURATED, 
"wbsm-lock recursion-counter saturated" );
		++m_exclusiveRecursionCount;
		return false;
	}
	if( internal_spin_lock_shared( cmp ) )
		return true;
	internal_lock_shared( cmp );
	return true;
}

void wbias_shared_mutex::unlock_exclusive( thread_id const &threadId )
{
	using namespace std;
	uint64_t cmp = m_atomic.load( memory_order_acquire );
	assert(check( cmp ));
	assert((cmp & EXCLUSIVE_FLAG_MASK) && m_exclusiveId == threadId);
	if( (cmp & EXCLUSIVE_FLAG_MASK) && m_exclusiveRecursionCount && 
m_exclusiveId == threadId )
	{
		--m_exclusiveRecursionCount;
		return;
	}
	m_exclusiveId = thread_id();
	for( ; ; )
	{
		assert(check( cmp ));
		assert(cmp & EXCLUSIVE_FLAG_MASK);
		if( (cmp & WAITING_EXCLUSIVE_MASK) != 0 )
			if( m_atomic.compare_exchange_weak( cmp, cmp - 
WAITING_EXCLUSIVE_VALUE, memory_order_release, memory_order_relaxed ) )
			{
				exc_terminate_or_spin( [&]() { m_releaseExclusiveSem.release( 1 ); } );
				return;
			}
			else
				continue;
		if( (cmp & WAITING_SHARERS_MASK) != 0 )
		{
			uint64_t waitingSharers = cmp & WAITING_SHARERS_MASK,
			         wakeups = waitingSharers >> WAITING_SHARERS_BASE;
			if( m_atomic.compare_exchange_weak( cmp, (cmp & ~EXCLUSIVE_FLAG_MASK) 
- waitingSharers + wakeups, memory_order_release, memory_order_relaxed ) )
			{
				exc_terminate_or_spin( [&]() { m_releaseSharedSem.release( 
(unsigned)wakeups ); } );
				return;
			}
			else
				continue;
		}
		if( m_atomic.compare_exchange_weak( cmp, 0, memory_order_release, 
memory_order_relaxed ) )
			return;
	}
}

// throws wbsm_exception if waiting sharers counter saturates
// (lock remains exclusive)

void wbias_shared_mutex::exclusive_to_shared( bool force )
{
	using namespace std;
	uint64_t cmp = m_atomic.load( std::memory_order_relaxed );
	assert((cmp & EXCLUSIVE_FLAG_MASK) && m_exclusiveRecursionCount == 0);
	if( m_maxSharedSpinCount > 0 )
	{
		int32_t maxSpin = (int32_t)m_sharedSpinCount * 2 + 10;
		maxSpin = maxSpin <= m_maxSharedSpinCount ? maxSpin : 
m_maxSharedSpinCount;
		int32_t spinCount = 0;
		bool setSpinCount = true;
		for( ; ; )
		{
			assert(check( cmp ));
			uint64_t wakeups = ((cmp & WAITING_SHARERS_MASK) >> 
WAITING_SHARERS_BASE) + (cmp & SHARERS_MASK);
			if( wakeups >= SHARERS_MASK )
			{
				setSpinCount = false;
				break;
			}
			if( !force )
				cmp &= ~WAITING_EXCLUSIVE_MASK;
			if( m_atomic.compare_exchange_weak( cmp, (cmp & ~EXCLUSIVE_FLAG_MASK) 
+ wakeups + SHARER_VALUE,
			                                    memory_order_release, 
memory_order_relaxed ) )
			{
				if( wakeups )
					exc_terminate_or_spin( [&]() { m_releaseSharedSem.release( 
(unsigned)wakeups ); } );
				m_sharedSpinCount += ((int16_t)spinCount - m_sharedSpinCount) / 8;
				return;
			}
			if( ++spinCount >= maxSpin )
				break;
			cpu_pause();
		}
		if( setSpinCount )
			m_sharedSpinCount += ((int16_t)spinCount - m_sharedSpinCount) / 8;
	}
	thread_id recoverThreadId = m_exclusiveId;
	m_exclusiveId = thread_id();
	for( ; ; )
	{
		assert(check( cmp ));
		uint64_t waitingSharers = cmp & WAITING_SHARERS_MASK,
		         wakeups = waitingSharers >> WAITING_SHARERS_BASE;
		if( !(cmp & WAITING_EXCLUSIVE_MASK) || force )
		{
			if( wakeups == SHARERS_MASK )
			{
				m_exclusiveId = recoverThreadId;
				throw wbsm_exception( wbsm_exception::SHARER_COUNTER_SATURATED, 
"wbsm-lock sharer-counter saturated" );
			}
			if( m_atomic.compare_exchange_weak( cmp, (cmp & ~EXCLUSIVE_FLAG_MASK) 
- waitingSharers + wakeups + SHARER_VALUE, memory_order_release, 
memory_order_relaxed ) )
			{
				if( wakeups )
					exc_terminate_or_spin( [&]() { m_releaseSharedSem.release( 
(unsigned)wakeups ); } );
				return;
			}
			else
				continue;
		}
		if( wakeups == SHARERS_MASK )
		{
			m_exclusiveId = recoverThreadId;
			throw wbsm_exception( wbsm_exception::SHARER_COUNTER_SATURATED, 
"wbsm-lock sharer-counter saturated" );
		}
		if( m_atomic.compare_exchange_weak( cmp, cmp - WAITING_EXCLUSIVE_VALUE 
+ WAITING_SHARERS_VALUE, memory_order_release, memory_order_relaxed ) )
		{
			exc_terminate_or_spin( [&]() { m_releaseExclusiveSem.release( 1 ); } );
			exc_terminate_or_spin( [&]() { m_releaseSharedSem.acquire(); });
			return;
		}
	}
}

inline
void wbias_shared_mutex::cpu_pause()
{
#if defined(_MSC_VER) || defined(__GNUC__) && (defined(__x86_64__) || 
defined(__i386__))
	_mm_pause();
#else
	#error "need platform-specific pause-instruction"
#endif
}

std::int16_t wbias_shared_mutex::max_exclusive_spin_count( std::int16_t 
max )
{
	std::swap( max, m_maxExclusiveSpinCount );
	return max;
}

std::int16_t wbias_shared_mutex::max_shared_spin_count( std::int16_t max )
{
	std::swap( max, m_maxSharedSpinCount );
	return max;
}

void wbsm_lock::set_state( std::uint8_t state, wbias_shared_mutex &mtx )
{
	xassert(state == wbsm_lock::UNLOCKED || state == wbsm_lock::SHARED || 
state == wbsm_lock::EXLUSIVE);
	switch( state )
	{
	case wbsm_lock::UNLOCKED:
		unlock();
		break;
	case wbsm_lock::SHARED:
		lock_shared( mtx );
		break;
	case wbsm_lock::EXLUSIVE:
		lock_exclusive( mtx );
		break;
	}
}

[toc] | [prev] | [next] | [standalone]


#83839

FromMuttley@dastardlyhq.com
Date2022-04-28 15:25 +0000
Message-ID<t4ebl5$323$1@gioia.aioe.org>
In reply to#83835
On Thu, 28 Apr 2022 13:11:48 +0200
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>Am 28.04.2022 um 12:54 schrieb Paavo Helde:
>> 28.04.2022 11:40 Muttley@dastardlyhq.com kirjutas:
>>> On Wed, 27 Apr 2022 18:56:06 +0200
>>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>>> If I need 3 level locking (which I do in most threaded programs) 
>>>>> then its
>>>>> pthreads for me because the simpleton C++ threading model doesn't 
>>>>> support it.
>>>>
>>>>
>>>> What's "3 level locking" ? Description / URL ?
>>>
>>> You are kidding me, right? You spout off about threading all the time and
>>> you don't know the fundamentals? Educate yourself:
>>>
>>> https://www.ibm.com/docs/en/aix/7.2?topic=programming-using-readwrite-locks 
>
>>>
>> 
>> And read-write locks have been in C++ standard since 2017:
>> https://en.cppreference.com/w/cpp/thread/shared_mutex
>
>This kind of shared lock is almost useless since it gives
>readers priority over writers so that the writer can proceed
>only if all readers have relinquished ownership. With my
>shared lock, all further readers are enqueued when a writer
>wants to gain ownership and the lock lets proceed the preceding
>readers.

So what does your code do if there are still threads reading the data and
another wants to write? Suddenly block the read threads and revoke their locks?
Otherwise how do you solve the "all readers have relinquished ownership" 
problem?

>Here's the code:

What a fucking mess.

[toc] | [prev] | [next] | [standalone]


#83841

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-04-28 17:30 +0200
Message-ID<t4ebu5$1o7$1@dont-email.me>
In reply to#83839
> So what does your code do if there are still threads reading the data and
> another wants to write? Suddenly block the read threads and revoke their locks?
> Otherwise how do you solve the "all readers have relinquished ownership"
> problem?

It behaves exactly like other shared locks, but once a writer has
registered as wanting to have write-access all further readers are
enqueued.


>> Here's the code:

> What a fucking mess.

No, working elegant code.

[toc] | [prev] | [next] | [standalone]


Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →

Back to top | Article view | comp.lang.c++


csiph-web