Saturday, May 11, 2019

Digest for comp.lang.c++@googlegroups.com - 17 updates in 6 topics

anhongleetcode@gmail.com: May 10 11:49PM -0700

Recently I found this is not working....
I am trying to insert a vector itself to its end.
 
Here people even complains that v.push_back(p.front()) won't work!
https://www.reddit.com/r/cpp/comments/vog1p/a_commonly_unknown_stdvector_pitfall/
 
 
I tried, the v.push_back(v.front()) for my gcc8 works.
But the following code doesn't
 
Experts, why this is implemented as NOT WORKING?
It's for me as can't understand.
 
Thanks,
Anhong
 
 
 
#include <vector>
#include <string>
 
int main()
{
std::vector<std::string> v
{
"1",
"2",
"3",
};
 
v.push_back(v.front());
 
for(int i = 0; i < 2; ++i){
v.insert(v.end(), v.begin(), v.begin() + 3);
}
 
return 0;
}
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 11 09:37AM +0200

> I am trying to insert a vector itself to its end.
 
> Here people even complains that v.push_back(p.front()) won't work!
> https://www.reddit.com/r/cpp/comments/vog1p/a_commonly_unknown_stdvector_pitfall/
 
That's incorrect, as also noted by Stephan T. Lavavej (the person in
charge of STL maintenance at Microsoft) in a comment there.
 
 
> }
 
> return 0;
> }
 
Works for me with both Visual C++ 2017 and MinGW g++ 8.2 compilers.
 
And I don't see any practical reason why it shouldn't work, since the
vector code can easily detect copying from self and ensure a
sufficiently large new buffer if necessary.
 
Can you provide an example, with the compiler version & invocation,
where it doesn't work according to your expectations?
 
 
Cheers!,
 
- Alf
Bonita Montero <Bonita.Montero@gmail.com>: May 11 10:07AM +0200

> Works for me with both Visual C++ 2017 and MinGW g++ 8.2 compilers.
 
LOL.
Manfred <noname@invalid.add>: May 11 07:31PM +0200

On 5/11/19 9:37 AM, Alf P. Steinbach wrote:
>> https://www.reddit.com/r/cpp/comments/vog1p/a_commonly_unknown_stdvector_pitfall/
 
> That's incorrect, as also noted by Stephan T. Lavavej (the person in
> charge of STL maintenance at Microsoft) in a comment there.
 
The comments refers to:
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#526
Which says:
"vector::insert(iter, value) is required to work because the standard
doesn't give permission for it not to work."
 
Which is obvious if value is an actual value, and 23.2.3 p4 describes
a.insert(p,t) where "t denotes an lvalue or a const rvalue of
X::value_type" (p3), but:
23.3.6.1 says the signature of front is:
const_reference front() const;
23.3.6.5 specifies:
iterator insert(const_iterator position, const T& x);
that takes a const reference, and specifies:
"Causes reallocation if the new size is greater than the old capacity" (p1)
and 23.3.6.3 (vector capacity) clarifies that:
"Reallocation invalidates all the references, pointers, and iterators
referring to the elements in the sequence" (p6)
 
So, I am most probably missing something, because to me there is some
unclarity between "lvalue or const rvalue of X:value_type" of 23.2.3
(requirements for sequence containers) and "const reference to T" of
23.3.6 (vector member signatures).
 
Anyway, since defect 526 has been closed as "not a defect" by the
committee, it can probably be trusted to work, and in fact it works for
gcc 8.3
 
 
>>      return 0;
>> }
 
> Works for me with both Visual C++ 2017 and MinGW g++ 8.2 compilers.
 
It doesn't work with gcc 8.3
 
 
> And I don't see any practical reason why it shouldn't work, since the
> vector code can easily detect copying from self and ensure a
> sufficiently large new buffer if necessary.
 
No, 23.2.3 p4 clearly states the pre-condition for
a.insert(p, i, j)
"i and j are not iterators into a."
 
And in fact i and j are invalidated by insert if a reallocation occurs.
 
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 11 10:49PM +0200

On 11.05.2019 19:31, Manfred wrote:
>>> }
 
>> Works for me with both Visual C++ 2017 and MinGW g++ 8.2 compilers.
 
> It doesn't work with gcc 8.3
 
Oh.
 
 
 
> No, 23.2.3 p4 clearly states the pre-condition for
> a.insert(p, i, j)
> "i and j are not iterators into a."
 
I overlooked that one, thanks!
 
In C++17 it's in table 87 in §25.2.3/4, a.k.a. §sequence.reqmts/4.
 
Thinking about it, it's probably due to the design where the iterators
are general /input iterators/, which I didn't notice either. So one
could define some custom stream like iterators that read from a vector,
and try to use those to insert into the same vector, and wham bang. It
seems the wording covers that, by excluding "iterators into a".
 
I didn't think of that.
 
But now that I do, I still don't see any practical reason for it. One
could change the design to have the general input iterator based insert
called `insert_input`, add a random iterator based `insert`, and allow
the former to be optimized by deferring to the latter when iterator
traits say the iterators are actually random access. The random iterator
based `insert` can easily check for self-referencing iterators by using
`std::less` (say, because total ordering) on the item pointers.
 
Then the no-self-ref requirement would be only on `insert_input`.
 
 
> And in fact i and j are invalidated by insert if a reallocation occurs.
 
Yes but as I see it, considering not just how conceptually easy this is
to implement (though it would be some coding work to do it) but that at
least two such implementations apparently exist, that's irrelevant. The
iterators are then valid before the operation, and invalid after, but
that's all that one can say. One cannot conclude anything about the
operation's success or well-defined-ness from that, as I see it.
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 12 12:25AM +0200

On 11.05.2019 22:49, Alf P. Steinbach wrote:
> based `insert` can easily check for self-referencing iterators by using
> `std::less` (say, because total ordering) on the item pointers.
 
> Then the no-self-ref requirement would be only on `insert_input`.
 
Here's how I envision a `std::vector` design without the self reference
trap, like (the just sufficient for the OP's example) `my::Vec` below:
 
 
-----------------------------------------------------------------------
#include <vector>
#include <string>
#include <functional> // std::(less_or_equal)
#include <iterator> // std::iterator_traits
#include <memory> // std::addressof
#include <type_traits> // std::is_same_v
#include <utility> // std::(enable_if_t, move)
 
namespace my{
using std::addressof, std::move, std::random_access_iterator_tag;
 
template< bool condition >
using Enable_if_ = std::enable_if_t<condition>;
 
template< class A, class B >
constexpr bool is_same_type_ = std::is_same_v<A, B>;
 
template< class T >
using It_category_ = typename
std::iterator_traits<T>::iterator_category;
 
template< class Item >
class Vec:
private std::vector<Item>
{
using Base = std::vector<Item>;
public:
using iterator = typename Base::iterator;
using const_iterator = typename Base::const_iterator;
using Index = typename Base::difference_type;
 
using Base::begin;
using Base::cbegin;
using Base::data;
using Base::end;
using Base::front;
using Base::push_back;
using Base::reserve;
using Base::size;
 
template<
class Rnd_it,
class = Enable_if_<is_same_type_<
It_category_<Rnd_it>,
random_access_iterator_tag
 
auto insert(
const const_iterator position,
const Rnd_it first,
const Rnd_it last )
-> iterator
{
const Index i_position = position - cbegin();
iterator pos = begin() + i_position;
if( first == last ) {
return pos;
}
 
const auto p_first = addressof( *first );
constexpr auto less_or_equal = std::less_equal<const Item*>();
 
if( less_or_equal( data(), p_first ) and
less_or_equal( p_first, data() + size() ) ) {
Vec copies( first, last );
reserve( size() + (last - first) );
for( Item& item: copies ) {
pos = Base::insert( pos, move( item ) );
}
return pos;
}
 
return Base::insert( position, first, last );
}
 
template< class Input_it>
auto insert_input(
const const_iterator position,
const Input_it first,
const Input_it last
) -> iterator
{
using Rnd_tag = random_access_iterator_tag;
if constexpr( is_same_type_<It_category_<Input_it>,
Rnd_tag> ) {
return insert( position, first, last );
} else {
return Base::insert( position, first, last );
}
}
 
using Base::Base;
};
 
} // namespace my
 
auto main()
-> int
{
my::Vec<std::string> v
{
"1",
"2",
"3",
};
 
v.push_back(v.front());
 
for( int i = 0; i < 2; ++i ) {
v.insert( v.end(), v.begin(), v.begin() + 3 );
}
return v.size();
}
-----------------------------------------------------------------------
 
 
> [snip]
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 12 12:53AM +0200

On 12.05.2019 00:25, Alf P. Steinbach wrote:
> [code with a 2 little bugs]
 
Strange that I should introduce bugs in something so simple. But then
it's late in the day, and I'm an old man (sort of). So it's not
guaranteed that this fixed code is entirely bug-free either.
 
 
#include <assert.h>
#include <vector>
#include <string>
#include <functional> // std::(less_or_equal)
#include <iterator> // std::iterator_traits
#include <memory> // std::addressof
#include <type_traits> // std::is_same_v
#include <utility> // std::(enable_if_t, move)
 
namespace my{
using std::addressof, std::move, std::random_access_iterator_tag;
 
template< bool condition >
using Enable_if_ = std::enable_if_t<condition>;
 
template< class A, class B >
constexpr bool is_same_type_ = std::is_same_v<A, B>;
 
template< class T >
using It_category_ = typename
std::iterator_traits<T>::iterator_category;
 
template< class Item >
class Vec:
private std::vector<Item>
{
using Base = std::vector<Item>;
public:
using iterator = typename Base::iterator;
using const_iterator = typename Base::const_iterator;
using Index = typename Base::difference_type;
 
using Base::begin;
using Base::cbegin;
using Base::data;
using Base::end;
using Base::front;
using Base::push_back;
using Base::reserve;
using Base::size;
 
template<
class Rnd_it,
class = Enable_if_<is_same_type_<
It_category_<Rnd_it>,
random_access_iterator_tag
 
auto insert(
const const_iterator position,
const Rnd_it first,
const Rnd_it last )
-> iterator
{
const Index i_position = position - cbegin();
if( first == last ) {
return begin() + i_position;
}
 
const auto p_first = addressof( *first );
constexpr auto less_or_equal = std::less_equal<const Item*>();
 
if( less_or_equal( data(), p_first ) and
less_or_equal( p_first, data() + size() ) ) {
Vec copies( first, last );
reserve( size() + (last - first) );
iterator pos = begin() + i_position;
for( Item& item: copies ) {
Base::insert( pos, move( item ) );
++pos;
}
return pos;
}
 
return Base::insert( position, first, last );
}
 
template< class Input_it>
auto insert_input(
const const_iterator position,
const Input_it first,
const Input_it last
) -> iterator
{
using Rnd_tag = random_access_iterator_tag;
if constexpr( is_same_type_<It_category_<Input_it>,
Rnd_tag> ) {
return insert( position, first, last );
} else {
return Base::insert( position, first, last );
}
}
 
using Base::Base;
};
 
} // namespace my
 
auto main()
-> int
{
my::Vec<std::string> v
{
"1",
"2",
"3",
};
 
v.push_back(v.front());
 
for( int i = 0; i < 2; ++i ) {
v.insert( v.end(), v.begin(), v.begin() + 3 );
}
return v.size();
}
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 12 01:01AM +0200

On 12.05.2019 00:53, Alf P. Steinbach wrote:
 
> Strange that I should introduce bugs in something so simple. But then
> it's late in the day, and I'm an old man (sort of). So it's not
> guaranteed that this fixed code is entirely bug-free either.
 
Yup, just two seconds after pressing "Send" in Thunderbird, I noticed
that an assignment was missing.
 
for( Item& item: copies ) {
pos = Base::insert( pos, move( item ) );
++pos;
}
 
 
So.
 
 
Cheers!,
 
- ALf
ram@zedat.fu-berlin.de (Stefan Ram): May 11 07:20PM

>I am trying to insert a vector itself to its end.
 
This would yield a circular vector!
 
First, tell the printer to not really print the expansion:
 
(setf *print-circle* t)
 
. With the helper function
 
(defun circular! (items) (setf (cdr (last items)) items))
 
we can then observe that
 
(circular! (list 1 2 3))
 
effectively is
 
( 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 ... )
 
.
ram@zedat.fu-berlin.de (Stefan Ram): May 11 10:41PM

>(circular! (list 1 2 3))
>( 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 ... )
 
Lurkers told my in e-mail that this is not C++.
 
So, here is my attempt to use a circular list in C++
using std-containers. The code "works" but I don't
know whether this behaviour is guaranteed by the
standard or just showing under my implementation!
 
main.cpp
 
#include <iostream>
#include <list>
 
int main()
{ ::std::list< int >l;
l.push_back( 2 );
l.push_back( 4 );
l.push_front( 7 );
int c {};
for( auto i = l.begin();; ++i )
{ if( i != l.end() )::std::cout << *i << '\n';
if( c++ > 20 )break; }}
 
transcript
 
7
2
4
7
2
4
7
2
4
7
2
4
7
2
4
7
2
woodbrian77@gmail.com: May 10 10:28PM -0700

Shalom
 
What's your opinion of this on-line code generator
https://github.com/Ebenezer-group/onwards
?
 
I think the need for quality software will increase
as time goes on. So I've been working on the code
generator and trying to improve it. I believe I've
been making progress, but I'll let you be the judge:
https://github.com/Ebenezer-group/onwards/blob/master/src/cmw/tiers/genz.cc
https://github.com/Ebenezer-group/onwards/blob/master/src/cmw/tiers/cmwA.cc
 
These are my repo topics:
cross-platform
hosted
middleware
network programming
on-line service
protocols
services
three-tier architecture
cpp-library
code generation
client-server
messaging
command-line tool
organic
disruptive-technology
Archimedes
Jerusalem
c-plus-plus
 
 
What do you think needs work? Thanks in advance.
 
 
Brian
Ebenezer Enteprises - Enjoying programming again.
http://webEbenezer.net
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: May 11 11:58AM +0100

> Shalom
 
> What's your opinion of this on-line code generator
> https://github.com/Ebenezer-group/onwards
 
You mean please look at my thinly disguised spam advert for my software
and website links to let you I am a misogynist homophobic bigot? You are
transparent, m8.
 
/Flibble
 
--
"You won't burn in hell. But be nice anyway." – Ricky Gervais
 
"I see Atheists are fighting and killing each other again, over who
doesn't believe in any God the most. Oh, no..wait.. that never happens." –
Ricky Gervais
 
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
woodbrian77@gmail.com: May 11 06:43AM -0700

On Saturday, May 11, 2019 at 5:58:57 AM UTC-5, Mr Flibble wrote:
 
> You mean please look at my thinly disguised spam advert for my software
> and website links to let you I am a misogynist homophobic bigot? You are
> transparent, m8.
 
Some people tried to label the Apostle Paul the same
way. History concluded differently. I'm proud to live
in St. Paul, Minnesota. There's also St. Peter, Minnesota,
St. Michael, Minnesota, Bethel, Minnesota (Bethel means
House of G-d in Hebrew).
 
I will venture to guess that you have not read "The Right
Side of History. How Reason and Moral Purpose Made the
West Great" by Ben Shapiro.
https://www.harpercollins.com/9780062857903/the-right-side-of-history/
 
You are kind of out of the loop here I'm afraid.
Best wishes.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 11 03:55AM -0700

Go to church this Sunday and experience God's grace, His forgiveness,
His towering love for you deep down.
 
https://mobile.twitter.com/KraigDay5/status/1127099958946140160
 
His love for you will overpower your troubles. All of them. You
can go to sleep at night knowing whose you are, and what your future
holds -- regardless of your Earthly circumstances.
 
His arms are open wide to embrace you with forgiveness for your sin,
and to give you eternal life in love and peace and joy and happiness.
It will free your mind like nothing else.
 
This is a true witness.
Love has a name.
His name is Jesus.
Trust Him. He will never let you down.
 
--
Rick C. Hodgin
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: May 11 12:00PM +0100

On 11/05/2019 11:55, Rick C. Hodgin wrote:
> Love has a name.
> His name is Jesus.
> Trust Him. He will never let you down.
 
Nonsense.
A) Your bible is false.
B) Your god the existence of which is predicated on your bible being true
is, given (A), also false.
 
/Flibble
 
--
"You won't burn in hell. But be nice anyway." – Ricky Gervais
 
"I see Atheists are fighting and killing each other again, over who
doesn't believe in any God the most. Oh, no..wait.. that never happens." –
Ricky Gervais
 
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
Jeff-Relf.Me @.@: May 10 09:02PM -0700

Bonita Montero <Bonita.Montero@gmail.com>: May 10 09:30PM +0200

> (ARM64 store exclusive) are made available as individual intrinsics
> since the code sequence between the LDEX and STREX must not, for
> example, include stores for proper operations.
 
Then the code around this intrinsics has to be suitable.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: