Alternatively you can avoid changing the iterator concept by changing the algorithms, leaning onto the elementwise logical negation operator ~.
For this to make sense you have to introduce a new type: an array of bools with an associated reduction operation - conjunction or disjunction, that would represent the equality comparison in each dimension and contextually convert to a boolean, by performing the reduction. The == operator will return such an array with conjunciton, since that's what makes more sense for the tuple in general. Now the logical ! in order to also remain sensible will need to negate the elements of the array AND change the conjunction to a disjunciton, adhering to De Morgan's law. The elementwise ~ however has no such obligations of logical consistency (it's wavy, it's chaotic, it's insaneee) and can happily just negate the elements leaving the reduction operation untouched. This coincidentally is both exactly what we need for loop conditions and exactly what we always had when working with integer types as bit vectors (so hopefully it shouldn't be that alien of a syntax). What I'm getting at is that the range based for loop and algorithms should use ~(first == last) instead of (first != last) as a loop condition. Unfortunately the (fisrt == last) for early returns and such, will turn into ~(first != last) with this approach... that's double negation... disgusting... and I forgot the #cpp in OP -_-
each logical component of a library should have:
smol brain: one file to represent it
big brain: one interface file and one implementation file to represent it
huge brain: one interface file, one type generic implementation file and one type specific implementation file to represent it
galaxy brain: one interface file, one type generic implementation file, one type specific inline implementation file, and one compilation unit file to rule them all, find them all, bring them all and in the darkness bind them all.
to all of the statistical nerds out there counting memory errors in #cpp to justify the existence of #rust: a logic error in a system that uses explicit memory management often culminates in a memory error. That doesn't make it a memory management error, it's still a logic error, and patching it up with more memory management is over-complicated at best and silently incorrect at worst.
this is roughly what your file format parsing library API should look like
https://en.cppreference.com/w/cpp/algorithm/mismatch
you must tell exactly where you stopped, what was there and, if it wasn't the end, what did you expect instead.
gotta love everyone advertising how header only their libraries are, as if that's some special feature requiring extra effort and not them just being lazy to do proper interface-implementation separation and provide an ABI.
every time
Q: why is this undefined behavior?
Everyone: undefined behavior means anything can happen, you cat will explode, your computer will get pregnant, yada yada, omg I love saying this over and over so much, i'm so smart, i know c++! what do you mean why?! standard says so!
No one: *actually explains why undefined, as opposed to unspecified or implementation defined*
another must have flag coming along to accompany -fno-rtti and -fno-ecxeptions, especially on embedded:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0881r7.html
"When the criteria for elision of a copy operation are met and the object to be copied is designated by an lvalue, or when the expression in a return statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue."
Now can I please have this for passing parameters and captures? Like if I say
return f(a,b,c);
or
return [a,b,c](){};
and any of of them a,b,c are automatic, they would get moved.
#cpp to the rescue as always
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3536.html
it's in c++14
would you write this
auto x = *it;
// modify it
if(error)
*it = x;
instead of this?
auto x = *it;
// modify x
if(ok)
*it = x;
me: noooo you can't just ignore deleted copy constructooor
#cpp: copy elision go brrrrrrrr
as promised my totally incomplete take on multidimensional iterators
I think I'm starting to slowly digest c++20 modules... it's basically pre-compiled headers done right + some language support for interface and implementation distinction.
pre c++20: logical component is a *header file* and bunch of *source files*.
post c++20: logical component is a *module interface file* and bunch of *module implementation files*.
pre: have to use an include guard to identify the *header files*, and name collisions cannot be diagnosed.
post: got a language level module name that compiler can diagnose, as there should be only one *module interface file*, identified by an export statement - two of those with the same name in a single translation unit is a conflict.
pre: no way to tell if a *header file* modification actually made a difference, changing a comment or white space can cause a massive recompilation chain reaction, as *header files* are just copied into the *source files*.
post: extra compilation step of *module interface file* allows the compiler to make a judgement about the nature of the modification, emitting a compiled interface file that other dependent modules use for compilation, instead of copying the text. This compiled interface does not change if you haven't actually meaningfully changed anything that is marked to be exported in the *module interface file*.
now what I don't get is what's going on with gcc's module mapper... why do you need an external server/file/program to map module names to files? Why don't just import the compiled interface file by name, and build up the dependency graph that way. My module files imports and depend on the compiled interface file of your module which depends on module interface file of your module... the module name to file name mapper seems like a whole lot of trouble for a minor convenience of having import and export declaration match exactly...
so what do you call a multidimensional iterator (multiple choice cause I got 2 slightly different implementations of the same thing)
freakin hate the freakin const and non const accessor duplication, when will this be fixed reeeeeeeeeeeee?!
third compiler bug already in this one feature I'm trying to implement -_-
https://godbolt.org/z/o5Mcv6Waa
seems fixed in trunk at least
what's with people and using int for bit twiddling?
the compilers are fighting over me again *swoon*
https://godbolt.org/z/feW5a5heP