Giter Site home page Giter Site logo

Comments (9)

jtv avatar jtv commented on August 16, 2024 1

@alexolog for some reason I think some conversation disappeared. But you're right — I wasn't aware of the operator[] requirement back when I wrote that code. So the result iterator is going to have to be a bidirectional iterator for now.

We'll probably need a deprecation period for the existing operator[] in the result iterator — which means we can't fully resolve this in 8.0. :-( On the one hand I see why the concept has that requirement (given how the classic C definition of the operator is just a combination of * and +). On the other hand it really gets in the way of the "referential transparency" that made so much sense in a two-dimensional iteration.

OTOH the row iterator is easy — that didn't have an operator[]. So in the short term I'm thinking...

  1. Degradate the result iterators to "bidirectional."
  2. Give the row iterators an operator[].

from libpqxx.

jtv avatar jtv commented on August 16, 2024

I thought I did the work for this, sometime long ago.

@alexolog do you know exactly which concepts are missing, and how I implement them?

from libpqxx.

jtv avatar jtv commented on August 16, 2024

I think we should be able to get some of the information by trying to instantiate a template that expects a std::random_access_iterator, but passing it a pqxx::const_row_iterator or a pqxx::const_result_iterator. There should be an error, and at least with some compilers, the error will tell us "this type doesn't satisfy the random_access_iterator concept because..."

@alexolog did you see a helpful error like that while compiling your code? (Switching between gcc and clang may help — I think they produce different error messages.

from libpqxx.

alexolog avatar alexolog commented on August 16, 2024

I thought I did the work for this, sometime long ago.

@alexolog do you know exactly which concepts are missing, and how I implement them?

Looking at LegacyRandomAccessIterator, we can see the requirements:

template< class I >
concept random_access_iterator =
	std::bidirectional_iterator<I> &&
	std::derived_from</*ITER_CONCEPT*/<I>, std::random_access_iterator_tag> &&
	std::totally_ordered<I> &&
	std::sized_sentinel_for<I, I> &&
	requires(I i, const I j, const std::iter_difference_t<I> n) {
		{ i += n } -> std::same_as<I&>;
		{ j +  n } -> std::same_as<I>;
		{ n +  j } -> std::same_as<I>;
		{ i -= n } -> std::same_as<I&>;
		{ j -  n } -> std::same_as<I>;
		{  j[n]  } -> std::same_as<std::iter_reference_t<I>>;
	};

It appears you have most of them, and the only one missing is operator[]. Implement that one and you're golden.

from libpqxx.

alexolog avatar alexolog commented on August 16, 2024

I think we should be able to get some of the information by trying to instantiate a template that expects a std::random_access_iterator, but passing it a pqxx::const_row_iterator or a pqxx::const_result_iterator. There should be an error, and at least with some compilers, the error will tell us "this type doesn't satisfy the random_access_iterator concept because..."

@alexolog did you see a helpful error like that while compiling your code? (Switching between gcc and clang may help — I think they produce different error messages.

See the example code I included in the original post.
We can find the iterator category by using if constexpr instead of SFINAE.
Both result and row iterator types satisfy bidirectional_iterator and below, but not random_access_iterator or above.

from libpqxx.

jtv avatar jtv commented on August 16, 2024

Implementing operator[] isn't so easy. The result iterator already has an operator, but it does something different.

from libpqxx.

alexolog avatar alexolog commented on August 16, 2024

Implementing operator[] should be easy since
image

Giving it different semantics (or omitting it altogether) means that the iterator won't be treated as a random-access iterator by libraries (including the standard library), which will, at best, choose to invoke operator++ in a loop instead of the more efficient operator+ (e.g., std::distance), or flatly refuse to accept it in some cases (e.g., std::flat_set<> or std::sort)

This is of course a valid design choice, but you cannot have your cake and eat it too. So the options are:

  1. (re)implement operator[] with the expected semantics to have the iterators model std::random_access_iterator, or
  2. declare the iterators as bidirectional (using iterator_category = std::bidirectional_iterator_tag;) and document them as such.

(Issue renamed accordingly)

from libpqxx.

jtv avatar jtv commented on August 16, 2024

We should be able to resolve this together with #770. Rewrite the iterator types so that they're no longer closely intertwined with the row/field types; give row and const_result_iterator different operator[]s with different return types; and also make row and field keep their result object alive but no longer make the result/row iterators keep their result alive.

from libpqxx.

jtv avatar jtv commented on August 16, 2024

Tempting: it now looks like a "divorce" between result::const_iterator::operator[] and row::operator[] probably wouldn't break a lot of code!

I tried commenting out the operator[] on the iterator, and the only code that failed to compile was in tests specifically meant to exercise this kind of thing. The "natural" code I'd written in other tests remained unaffected.

So loath as I am to break compatibility like this, I probably could implement random_access_iterator in libpqxx 8.0.

(For now though, going with the demotion to bidirectional_iterator.)

from libpqxx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.