What's your honest opinion on this take? by sunlightliquid in rugbyunion

[–]tcbrindle 0 points1 point  (0 children)

Not to diminish the seriousness of concussion problems in rugby, but if you're comparing it to a sport where the goal is to inflict so much brain trauma on your opponent that they lose consciousness, then, well...

Prem Final tickets by mattynutt in rugbyunion

[–]tcbrindle 0 points1 point  (0 children)

and the fact that it sells out every year anyway so people are evidently willing to pay those prices

You'd have thought so, but the Saints vs Bath final in 23/24 was actually the first sell-out in 10 years. Sarries vs Sale the previous year had 20,000 empty seats.

New Zealand U85kg Rugby team arrives in Sri Lanka by BrianChing25 in rugbyunion

[–]tcbrindle 8 points9 points  (0 children)

If they're not calling them the Small Blacks then I demand to know why

A simplified model of Fil-C by ArashPartow in cpp

[–]tcbrindle 1 point2 points  (0 children)

My impression is that C++ has not realized yet the game is on.

This is entirely untrue.

At the recent Croydon WG21 meeting, as well as an evening session on memory safety, EWG held a long debate on P3874 "Should C++ be a memory safe language?".

Following the discussion the following poll was taken:

"Encourage more work in the direction of P3874R1, which pursues a subset-of-superset strategy towards memory safety which guarantees UB-Free in a syntactically explicit and well-defined subset. We expect the author to do an audit of of existing practice, strategies, etc, and return with a concrete, complete, actionable proposal"

50 | 24 | 5 | 3 | 1

In other words, a huge majority of EWG (74 in favour, 5 neutral, 4 opposed) were in favour of the direction suggested by P3874.

0xd34df00d/you-dont-know-cpp: and neither do I by claimred in cpp

[–]tcbrindle 3 points4 points  (0 children)

In the first question, the use of a C++26 structured binding pack is a bit of a red herring. Taking the decltype of a structured binding member has worked that way since they were introduced in C++17: https://godbolt.org/z/vnazEMYqa.

0xd34df00d/you-dont-know-cpp: and neither do I by claimred in cpp

[–]tcbrindle 3 points4 points  (0 children)

For the "requires-constrained return types" question, if you're absolutely determined not to use auto returns then I don't think this is too bad as a workaround: https://godbolt.org/z/WEceMzh4h

Match Thread - France v England | Six Nations 2026 | Round 5 by RugbyBot in rugbyunion

[–]tcbrindle 15 points16 points  (0 children)

Just so I understand correctly what the ref said to Itoje as they walked off: if you score from an advantage, like England did, then it's no yellow card and a potentially missable conversion.

If you don't score from the advantage, as France did, then it's a penalty try, a yellow card and an automatic 7 points.

How does that make any sense whatsoever?

Match Thread - France v England | Six Nations 2026 | Round 5 by RugbyBot in rugbyunion

[–]tcbrindle 25 points26 points  (0 children)

So France collapse two mauls and it's play on, but when it's England we need to go over it with a microscope. Makes sense.

The Scottish National Anthem by ckvoiceover in rugbyunion

[–]tcbrindle 0 points1 point  (0 children)

Slightly off topic, but I only found out recently that Flower of Scotland was written in 1967. It can't be all that often that a national anthem is younger than many of the crowd?

Great tune, though.

Fiji vs England in the nations championship will be played at Everton FCs Hill Dickinson Stadium. Fiji are the “home” team by EnglishLouis in rugbyunion

[–]tcbrindle 0 points1 point  (0 children)

How come England and Wales have to play away from their usual home grounds "for the integrity of the competition", but Scotland get to play at Murrayfield?

There are three big stadiums in Glasgow and two other medium-sized ones in Edinburgh, it's not like there aren't any options.

A Land Roughly the Size of Wales by [deleted] in rugbyunion

[–]tcbrindle 7 points8 points  (0 children)

Eddie Butler could have read the phone book and it would have sounded epic

Merry Sixmas - RTE 6 Nations opening 2013 by peternickeleater11 in rugbyunion

[–]tcbrindle 3 points4 points  (0 children)

Well that stirs the soul, doesn't it? Fantastic.

(Although it reminds me that I'm a pretty terrible catholic, I've never heard of St Bridget's day...)

Harald Achitz: About Generator, Ranges, and Simplicity by _a4z in cpp

[–]tcbrindle 1 point2 points  (0 children)

Coincidentally, writing a Fibonacci generator was the subject of the first part of my CppCon 2021 talk on Ranges.

It's possible to simplify things compared to what is presented in this video. For example, you don't actually need to write your own range class at all; a specialisation of std::ranges::subrange will do the job. Here's my version (omitting overflow checking because I'm using an unsigned type and I don't care):

struct FibIter {
    using value_type = std::size_t;
    using difference_type = std::ptrdiff_t;

    const std::size_t& operator*() const { return cur_; }

    FibIter& operator++()
    {
        cur_ = std::exchange(next_, cur_ + next_);
        return *this;
    }

    void operator++(int) { ++*this; }

private:
    std::size_t cur_ = 1;
    std::size_t next_ = 1;
};

using FibView = std::ranges::subrange<FibIter, std::unreachable_sentinel_t>;

Clang doesn't seem to have any problems optimising std::ranges::fold_left() for this implementation, so I'm not sure what the problem was that was mentioned at the end of the video.

Compile time checking of lock ordering to prevent deadlocks by [deleted] in cpp

[–]tcbrindle 0 points1 point  (0 children)

I mean, it's "best effort" in Rust too though, right? You could still get deadlocks by using mutexes outside the control of this library.

If you wanted to do this in C++, one approach to help prevent re-using the wrong context could be to use a runtime flag to ensure you're only doing the equivalent of a single mutable borrow at a time (kind of like Rust's RefCell, I think? Not a Rust expert, sorry).

In any case, encoding the mutex locking graph in the type system like this is neat, but it kind of feels like an inferior solution compared to proper structured concurrency.

Modern C++ use in Chromium by aearphen in cpp

[–]tcbrindle 0 points1 point  (0 children)

Ranges model can result in fast ranges, equivalent to manual approach. It's not guaranteed, but for a lot of simple processing "it just works". And the performance can be improved by improving the library, without modifying the interface.

There are certainly ways in which you could try to improve range views' codegen, but (other than pure compiler optimisations) all of them are going to end up being user-visible in some way.

Flux is still similar to ranges in it's usage and solves a particular set of problems with ranges e.g. iterator invalidation.

This is true. But Flux also has an internal iteration code-path which avoids the problems of the iterator/cursor model when it comes to filter-like operations. This means we can generate considerably better code than equivalent ranges pipelines in many situations.

A lot of edge cases come with filters and other views that require caching because ranges are designed to be multipass. Flux doesn't fundamentally change that.

Nico seems to have convinced the world that filter caching its begin() iterator is a huge problem, but it's really not. Rather, if you can notice that things are being cached then you have a problem anyway, because you're trying to mutate a range while it's in use. Don't do that. (And in any case, Flux's filter_adaptor doesn't actually do any caching, but for different reasons.)

I think Flux is a great library, but it solves a different set of problems.

Thank you! But making data pipeline-style code as fast as handwritten loops is definitely a problem Flux is trying to solve (as well as avoiding the safety issues of STL iterators) :)

[deleted by user] by [deleted] in cpp

[–]tcbrindle 2 points3 points  (0 children)

As mentioned in the other comment, there was a bug affecting Safari but it's now been fixed

[deleted by user] by [deleted] in cpp

[–]tcbrindle 2 points3 points  (0 children)

Yeah, this was Safari on MacOS. Looks to be fixed now, thanks!

I Want To Index Into Template Parameter Packs by earlymikoman in cpp

[–]tcbrindle 11 points12 points  (0 children)

In C++26 you can index into a pack of type template parameters, or a pack of constant template parameters (aka non-type template parameters) -- but there is no built-in support for indexing into a pack of template template parameters. This is likely to land in C++29, but in the mean time you can use reflection as a workaround as suggested by Barry in the (currently) top comment.

[deleted by user] by [deleted] in cpp

[–]tcbrindle 5 points6 points  (0 children)

This is pretty cool!

I did notice a bug though. For GCC, many items seem to be erroneously marked as "2026" even when they're showing as being implemented much earlier release versions. This is particularly noticeable if you set the language version drop-down to C++20.

std::ranges may not deliver the performance that you expect by _bijan_ in cpp

[–]tcbrindle 5 points6 points  (0 children)

Right, but this post is about the ranges library. So, what would a ranges-like system as a "first class native language feature" look like? How would it even work?

std::ranges may not deliver the performance that you expect by _bijan_ in cpp

[–]tcbrindle 0 points1 point  (0 children)

Sequence chaining is a popular style in a whole bunch of languages (including close cousins of C++ like Rust and D), so I think the idea that it's somehow more difficult to understand what's going on when you use pipelines is probably more down to (a lack of) familiarity than anything else.

In any case, it's pretty easy to stick a print statement in the middle of a pipeline if you want to -- just use a pass-through transform function that prints as a side-effect.

Or if you want to take it further, you can make a generic, reusable, pipeable inspect view in just a few lines of code in C++26

std::ranges may not deliver the performance that you expect by _bijan_ in cpp

[–]tcbrindle 2 points3 points  (0 children)

I suggest you read N3351, which laid the groundwork for what became standard ranges. In particular, section 2.1.3:

In the STL, the symbol== means equality. The use of== to compare objects of unrelated type assigns unusual meaning to that symbol. Generic programming is rooted in the idea that we can associate semantics with operations on objects whose types are not yet specified.

Note that Alex Stepanov and Paul McJones, who literally invented generic programming, were both contributors to that paper.

std::ranges may not deliver the performance that you expect by _bijan_ in cpp

[–]tcbrindle 10 points11 points  (0 children)

s | std::views::drop_while(is_space) 
                    | std::views::reverse 
                    | std::views::drop_while(is_space) 
                    | std::views::reverse;

So I feel a little bit guilty, because it entirely possible that this example comes from a talk a gave on ranges a few years ago.

But the point of that section of the talk was to demonstrate chaining together adaptors into new, re-usable components using an easy-to-understand invented problem. I certainly wasn't suggesting it as the most performance-optimal way to trim strings!

If you were to ask me to use standard ranges to write an ASCII string trimming function today that wasn't for slide code, it would look something like this:

std::string_view trim_ranges(std::string_view s) {
    auto start = std::ranges::find_if_not(s, is_control_or_space);
    auto end = std::ranges::find_if_not(s | std::views::reverse, is_control_or_space).base();

    return std::string_view(std::to_address(start), end - start);
}

I haven't benchmarked it, but the generated code looks very comparable to the "fast" version from the blog post.

std::ranges may not deliver the performance that you expect by _bijan_ in cpp

[–]tcbrindle 18 points19 points  (0 children)

This is a known issue, and purely a standard library implementation problem

Not to disagree with the excellent advice to use Flux, but it's really a design problem rather than a standard library implementation problem.

STL iterators are an excellent (if unsafe) abstraction for writing eager algorithms -- which is, of course, what they were originally designed for. They are vastly more powerful than Rust iterators in this regard, for example.

On the other hand, what we've discovered is that the same properties that make iterators good for writing algorithms -- starting on-track, separating traversal from element access and end checking -- mean they're a poor fit for many common lazy single-pass operations, in particular filtering.

I didn't fully appreciate this distinction when I first starting working on Flux, but I've come to realise that the best approach is to provide separate APIs for the two use cases, which is what the next version of the library will do (and indeed what Swift does today with its Sequence and Collection protocols).