Discussion:
General functions std::reverse and std::sort
Vlad from Moscow
2013-06-24 21:05:40 UTC
Permalink
In most cases standard algorithms (and some containers' member functions)
std::sort and std:;reverse are called over a whole container. For example

[code]
std::forward_list<int> f;
// filling the list
f.sort();
// or
f.sort( std::greater<int>() );

std::vector<int> v;
//filling the vector
std::sort( v.begin(), v.end() );
// or
std::sort( v.begin(), v.end(), std::greater<int>() );
[/code]

So I suggest to introduce general functions std::reverse and std::sort that
will accept the reference to a container.

Below a demostrative example that illustrates the proposal

[code]
#include <iostream>
#include <algorithm>
#include <iterator>
#include <functional>
#include <vector>
#include <forward_list>
#include <list>

namespace N1 // std
{

template <typename T>
void reverse( T &c )
{
std::reverse( std::begin( c ), std::end( c ) );
}

template <typename T, typename Allocator>
void reverse( std::forward_list<T, Allocator> &f )
{
f.reverse();
}

template <typename T, typename Allocator>
void reverse( std::list<T, Allocator> &l )
{
l.reverse();
}
template <typename T>
void sort( T &c )
{
std::sort( std::begin( c ), std::end( c ) );
}

template <typename T, typename Allocator>
void sort( std::forward_list<T, Allocator> &f )
{
f.sort();
}

template <typename T, typename Allocator>
void sort( std::list<T, Allocator> &l )
{
l.sort();
}
template <typename T, typename Compare>
void sort( T &c, Compare comp )
{
std::sort( std::begin( c ), std::end( c ), comp );
}

template <typename T, typename Allocator, typename Compare>
void sort( std::forward_list<T, Allocator> &f, Compare comp )
{
f.sort( comp );
}

template <typename T, typename Allocator, typename Compare>
void sort( std::list<T, Allocator> &l, Compare comp )
{
l.sort( comp );
}
} // end of N1
int main()
{
int a[3] = { 1, 2, 3 };
std::forward_list<int> f( std::begin( a ), std::end( a ) );
std::list<int> l( std::begin( a ), std::end( a ) );
std::vector<int> v( std::begin( a ), std::end( a ) );

std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;

N1::reverse( a );
N1::reverse( f );
N1::reverse( l );
N1::reverse( v );

std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;

N1::sort( a );
N1::sort( f );
N1::sort( l );
N1::sort( v );

std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;

N1::sort( a, std::greater<int>() );
N1::sort( f, std::greater<int>() );
N1::sort( l, std::greater<int>() );
N1::sort( v, std::greater<int>() );

std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
}
[/code]
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Zhihao Yuan
2013-06-24 21:09:21 UTC
Permalink
Post by Vlad from Moscow
In most cases standard algorithms (and some containers' member functions)
std::sort and std:;reverse are called over a whole container. For example
Don't worry. The Ranges study group is responsible for handling that.

--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://4bsd.biz/
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Vlad from Moscow
2013-06-24 21:11:50 UTC
Permalink
I am not worry I am making a proposal.
Post by Vlad from Moscow
Post by Vlad from Moscow
In most cases standard algorithms (and some containers' member
functions)
Post by Vlad from Moscow
std::sort and std:;reverse are called over a whole container. For
example
Don't worry. The Ranges study group is responsible for handling that.
--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://4bsd.biz/
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
m***@gmail.com
2013-06-24 23:10:17 UTC
Permalink
Honestly, I would be more interested in std::reversed and std::sorted on
containers, which could be handy to use with rnge-based for loopd than in
std::sort and std::reverse.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Vlad from Moscow
2013-06-24 23:29:30 UTC
Permalink
You can make a corresponding proposal.
Post by m***@gmail.com
Honestly, I would be more interested in std::reversed and std::sorted on
containers, which could be handy to use with rnge-based for loopd than in
std::sort and std::reverse.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
m***@gmail.com
2013-06-25 07:49:04 UTC
Permalink
Well, I thought I could write one once, but there were many design choices
that I did not overcome: for example,
my first intent was to create generator objects in order to iterate through
them (the feature was really made for
range-based for loops and almost not to be used anywhere else), but my
choices when trying to implement it
seemed clumsy.

Moreover, that was close to Boost's range adapters, so I finally decided to
wait to see if a more generic
mecanism could work with range instead of having specialized generator
functions lost somewhere into
<utility> (or any other standard header).

The generator I implemented could be used like this for example:

for (auto elem: std::reversed(container))
{
if (elem)
{
do_something();
break;
}
}

Whatever, it's probably wiser to wait for ranges before trying anything
else, unless reversed/sorted are
useful enough by themselves to undergo a proposal.
Post by Vlad from Moscow
You can make a corresponding proposal.
Post by m***@gmail.com
Honestly, I would be more interested in std::reversed and std::sorted on
containers, which could be handy to use with rnge-based for loopd than in
std::sort and std::reverse.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Vlad from Moscow
2013-06-27 10:07:52 UTC
Permalink
Your ideas are different than mine. So they do not contradict each other. I
want to have general functions sort and reverse even for classes that have
no iterators. The only condition they must satisfy is the presence of
their own member functions sort and reverse.
For the demontsrative example I selected the approach used for std:;swap
that only to illustrate the idea. However it would be better to write these
functions based on conditions

std::is_member_function_pointer<decltype( &Container::reverse)>::value
std::is_member_function_pointer<decltype( &Container::sort)>::value
Post by m***@gmail.com
Well, I thought I could write one once, but there were many design choices
that I did not overcome: for example,
my first intent was to create generator objects in order to iterate
through them (the feature was really made for
range-based for loops and almost not to be used anywhere else), but my
choices when trying to implement it
seemed clumsy.
Moreover, that was close to Boost's range adapters, so I finally decided
to wait to see if a more generic
mecanism could work with range instead of having specialized generator
functions lost somewhere into
<utility> (or any other standard header).
for (auto elem: std::reversed(container))
{
if (elem)
{
do_something();
break;
}
}
Whatever, it's probably wiser to wait for ranges before trying anything
else, unless reversed/sorted are
useful enough by themselves to undergo a proposal.
Post by Vlad from Moscow
You can make a corresponding proposal.
Post by m***@gmail.com
Honestly, I would be more interested in std::reversed and std::sorted on
containers, which could be handy to use with rnge-based for loopd than in
std::sort and std::reverse.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Martinho Fernandes
2013-06-27 10:10:10 UTC
Permalink
Post by Vlad from Moscow
Your ideas are different than mine. So they do not contradict each other. I
want to have general functions sort and reverse even for classes that have
no iterators. The only condition they must satisfy is the presence of their
own member functions sort and reverse.
For the demontsrative example I selected the approach used for std:;swap
that only to illustrate the idea. However it would be better to write these
functions based on conditions
std::is_member_function_pointer<decltype( &Container::reverse)>::value
std::is_member_function_pointer<decltype( &Container::sort)>::value
The conditions you want are whether or not
`decltype(std::declval<Container>().reverse())` and
`decltype(std::declval<Container>().sort())` cause substitution
failures.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Vlad from Moscow
2013-06-27 10:23:48 UTC
Permalink
So the task is to write appropriate overloaded functions based on these
conditions.

ÞÅÔ×ÅÒÇ, 27 ÉÀÎÑ 2013 Ç., 14:10:10 UTC+4 ÐÏÌØÚÏ×ÁÔÅÌØ R. Martinho Fernandes
Post by Vlad from Moscow
Post by Vlad from Moscow
Your ideas are different than mine. So they do not contradict each
other. I
Post by Vlad from Moscow
want to have general functions sort and reverse even for classes that
have
Post by Vlad from Moscow
no iterators. The only condition they must satisfy is the presence of
their
Post by Vlad from Moscow
own member functions sort and reverse.
For the demontsrative example I selected the approach used for std:;swap
that only to illustrate the idea. However it would be better to write
these
Post by Vlad from Moscow
functions based on conditions
std::is_member_function_pointer<decltype( &Container::reverse)>::value
std::is_member_function_pointer<decltype( &Container::sort)>::value
The conditions you want are whether or not
`decltype(std::declval<Container>().reverse())` and
`decltype(std::declval<Container>().sort())` cause substitution
failures.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
'Vlad from Moscow' via ISO C++ Standard - Future Proposals
2018-10-05 14:51:40 UTC
Permalink
It seems using requires expressions it is not difficult to write the
general function sort and reverse.

I do not know yet requires expressions enough well but the initial
implementation an look for example the following way. It can be further
elaborated.

Here is a demonstrative program

#include <iostream>

#include <forward_list>
#include <vector>
#include <iterator>
#include <algorithm>


template <typename Container>
void sort( Container &container ) requires requires() { &Container::sort; }
{
std::cout << "sort with requires is called.\n";
container.sort();
}


template <typename Container>
void sort( Container &container )
{
std::cout << "sort without requires is called.\n";
std::sort( std::begin( container ), std::end( container ) );
}


template <typename Container>
void reverse( Container &container ) requires requires() { &Container::
reverse; }
{
std::cout << "reverse with requires is called.\n";
container.reverse();
}


template <typename Container>
void reverse( Container &container )
{
std::cout << "reverse without requires is called.\n";
std::reverse( std::begin( container ), std::end( container ) );
}


int main()
{
std::forward_list<int> lst = { 3, 2, 1 };

for ( const auto &item : lst ) std::cout << item << ' ';
std::cout << '\n';

sort( lst );


for ( const auto &item : lst ) std::cout << item << ' ';
std::cout << '\n';


reverse( lst );



for ( const auto &item : lst ) std::cout << item << ' ';
std::cout << '\n';


std::cout << '\n';

std::vector<int> v = { 3, 2, 1 };


for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';

sort( v );


for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';


reverse( v );


for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';


std::cout << '\n';


int a[] = { 3, 2, 1 };

for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';

sort( a );


for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';


reverse( a );


for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
}



So I am going to put your attention to this propoisal of general functions
*std::sort* and *std::reverse*. Of course another set of the function sort
should be with a second parameter that specifies the comparison.


четверг, 27 ОюМя 2013 г., 14:23:48 UTC+4 пПльзПватель Vlad from Moscow
Post by Vlad from Moscow
So the task is to write appropriate overloaded functions based on these
conditions.
четверг, 27 ОюМя 2013 г., 14:10:10 UTC+4 пПльзПватель R. Martinho
Post by Vlad from Moscow
Post by Vlad from Moscow
Your ideas are different than mine. So they do not contradict each
other. I
Post by Vlad from Moscow
want to have general functions sort and reverse even for classes that
have
Post by Vlad from Moscow
no iterators. The only condition they must satisfy is the presence of
their
Post by Vlad from Moscow
own member functions sort and reverse.
For the demontsrative example I selected the approach used for
std:;swap
Post by Vlad from Moscow
that only to illustrate the idea. However it would be better to write
these
Post by Vlad from Moscow
functions based on conditions
std::is_member_function_pointer<decltype( &Container::reverse)>::value
std::is_member_function_pointer<decltype( &Container::sort)>::value
The conditions you want are whether or not
`decltype(std::declval<Container>().reverse())` and
`decltype(std::declval<Container>().sort())` cause substitution
failures.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4158f558-6d0c-4b70-9cf2-54afa3d9686d%40isocpp.org.
'Vlad from Moscow' via ISO C++ Standard - Future Proposals
2018-10-07 13:53:31 UTC
Permalink
Maybe it is reasonable tp introduce also similar general functions like
find, lower_bound, upper_bound, equal_range.

пятМОца, 5 Пктября 2018 г., 18:51:40 UTC+4 пПльзПватель Vlad from Moscow
Post by 'Vlad from Moscow' via ISO C++ Standard - Future Proposals
It seems using requires expressions it is not difficult to write the
general function sort and reverse.
I do not know yet requires expressions enough well but the initial
implementation an look for example the following way. It can be further
elaborated.
Here is a demonstrative program
#include <iostream>
#include <forward_list>
#include <vector>
#include <iterator>
#include <algorithm>
template <typename Container>
void sort( Container &container ) requires requires() { &Container::sort; }
{
std::cout << "sort with requires is called.\n";
container.sort();
}
template <typename Container>
void sort( Container &container )
{
std::cout << "sort without requires is called.\n";
std::sort( std::begin( container ), std::end( container ) );
}
template <typename Container>
reverse; }
{
std::cout << "reverse with requires is called.\n";
container.reverse();
}
template <typename Container>
void reverse( Container &container )
{
std::cout << "reverse without requires is called.\n";
std::reverse( std::begin( container ), std::end( container ) );
}
int main()
{
std::forward_list<int> lst = { 3, 2, 1 };
for ( const auto &item : lst ) std::cout << item << ' ';
std::cout << '\n';
sort( lst );
for ( const auto &item : lst ) std::cout << item << ' ';
std::cout << '\n';
reverse( lst );
for ( const auto &item : lst ) std::cout << item << ' ';
std::cout << '\n';
std::cout << '\n';
std::vector<int> v = { 3, 2, 1 };
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
sort( v );
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
reverse( v );
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
std::cout << '\n';
int a[] = { 3, 2, 1 };
for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
sort( a );
for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
reverse( a );
for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
}
So I am going to put your attention to this propoisal of general functions
*std::sort* and *std::reverse*. Of course another set of the function
sort should be with a second parameter that specifies the comparison.
четверг, 27 ОюМя 2013 г., 14:23:48 UTC+4 пПльзПватель Vlad from Moscow
Post by Vlad from Moscow
So the task is to write appropriate overloaded functions based on these
conditions.
четверг, 27 ОюМя 2013 г., 14:10:10 UTC+4 пПльзПватель R. Martinho
Post by Vlad from Moscow
Post by Vlad from Moscow
Your ideas are different than mine. So they do not contradict each
other. I
Post by Vlad from Moscow
want to have general functions sort and reverse even for classes that
have
Post by Vlad from Moscow
no iterators. The only condition they must satisfy is the presence of
their
Post by Vlad from Moscow
own member functions sort and reverse.
For the demontsrative example I selected the approach used for
std:;swap
Post by Vlad from Moscow
that only to illustrate the idea. However it would be better to write
these
Post by Vlad from Moscow
functions based on conditions
std::is_member_function_pointer<decltype( &Container::reverse)>::value
std::is_member_function_pointer<decltype( &Container::sort)>::value
The conditions you want are whether or not
`decltype(std::declval<Container>().reverse())` and
`decltype(std::declval<Container>().sort())` cause substitution
failures.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/44e18e2a-13c7-46ec-8d5a-2d4b7acf0e95%40isocpp.org.
Justin Bassett
2018-10-07 16:32:01 UTC
Permalink
I believe ranges will fill this role. I'm not entirely familiar with it, so
I'm not sure if it allows you to write `std::ranges::sort(some_std_list)`
(I remember hearing that it does, though), but I believe it otherwise does
what you are talking about.

On Sun, Oct 7, 2018 at 6:53 AM 'Vlad from Moscow' via ISO C++ Standard -
Post by 'Vlad from Moscow' via ISO C++ Standard - Future Proposals
Maybe it is reasonable tp introduce also similar general functions like
find, lower_bound, upper_bound, equal_range.
пятМОца, 5 Пктября 2018 г., 18:51:40 UTC+4 пПльзПватель Vlad from Moscow
Post by 'Vlad from Moscow' via ISO C++ Standard - Future Proposals
It seems using requires expressions it is not difficult to write the
general function sort and reverse.
I do not know yet requires expressions enough well but the initial
implementation an look for example the following way. It can be further
elaborated.
Here is a demonstrative program
#include <iostream>
#include <forward_list>
#include <vector>
#include <iterator>
#include <algorithm>
template <typename Container>
void sort( Container &container ) requires requires() { &Container::sort; }
{
std::cout << "sort with requires is called.\n";
container.sort();
}
template <typename Container>
void sort( Container &container )
{
std::cout << "sort without requires is called.\n";
std::sort( std::begin( container ), std::end( container ) );
}
template <typename Container>
reverse; }
{
std::cout << "reverse with requires is called.\n";
container.reverse();
}
template <typename Container>
void reverse( Container &container )
{
std::cout << "reverse without requires is called.\n";
std::reverse( std::begin( container ), std::end( container ) );
}
int main()
{
std::forward_list<int> lst = { 3, 2, 1 };
for ( const auto &item : lst ) std::cout << item << ' ';
std::cout << '\n';
sort( lst );
for ( const auto &item : lst ) std::cout << item << ' ';
std::cout << '\n';
reverse( lst );
for ( const auto &item : lst ) std::cout << item << ' ';
std::cout << '\n';
std::cout << '\n';
std::vector<int> v = { 3, 2, 1 };
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
sort( v );
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
reverse( v );
for ( const auto &item : v ) std::cout << item << ' ';
std::cout << '\n';
std::cout << '\n';
int a[] = { 3, 2, 1 };
for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
sort( a );
for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
reverse( a );
for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
}
So I am going to put your attention to this propoisal of general
functions *std::sort* and *std::reverse*. Of course another set of the
function sort should be with a second parameter that specifies the
comparison.
четверг, 27 ОюМя 2013 г., 14:23:48 UTC+4 пПльзПватель Vlad from Moscow
Post by Vlad from Moscow
So the task is to write appropriate overloaded functions based on these
conditions.
четверг, 27 ОюМя 2013 г., 14:10:10 UTC+4 пПльзПватель R. Martinho
Post by Vlad from Moscow
Post by Vlad from Moscow
Your ideas are different than mine. So they do not contradict each
other. I
Post by Vlad from Moscow
want to have general functions sort and reverse even for classes that
have
Post by Vlad from Moscow
no iterators. The only condition they must satisfy is the presence of
their
Post by Vlad from Moscow
own member functions sort and reverse.
For the demontsrative example I selected the approach used for
std:;swap
Post by Vlad from Moscow
that only to illustrate the idea. However it would be better to write
these
Post by Vlad from Moscow
functions based on conditions
std::is_member_function_pointer<decltype(
&Container::reverse)>::value
Post by Vlad from Moscow
std::is_member_function_pointer<decltype( &Container::sort)>::value
The conditions you want are whether or not
`decltype(std::declval<Container>().reverse())` and
`decltype(std::declval<Container>().sort())` cause substitution
failures.
--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/44e18e2a-13c7-46ec-8d5a-2d4b7acf0e95%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/44e18e2a-13c7-46ec-8d5a-2d4b7acf0e95%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5dSTjC5U17XZDXU5%3D3Qj%3DtPMRSJ9%3DBr%2B3MnX3ytL8DFyg%40mail.gmail.com.
'Vlad from Moscow' via ISO C++ Standard - Future Proposals
2018-11-30 15:37:31 UTC
Permalink
I'm sorry.

It would be more correctly to define the function the following way
changing the return type tas it is shown
template <typename Container>
Container & sort( Container &container ) requires requires() { &Container::
sort; }
{
container.sort();

return container;
}

template <typename Container>
Container & sort( Container &container )
{
std::sort( std::begin( container ), std::end( container ) );

return container;
}


Consider for example this question of a beginner as me at Stackoverflow
https://stackoverflow.com/questions/53557881/checking-if-two-strings-are-anagram#

It is required to determine whether two strings are anagrams of each other.

One of approaches is to sort the strings and compare them.

Using the functions above the function that determines whether strings are
anagrams can be written easy.

#include <iostream>
#include <iomanip>
#include <string>
#include <iterator>
#include <algorithm>

template <typename Container>
Container & sort( Container &container ) requires requires() { &Container::
sort; }
{
container.sort();

return container;
}

template <typename Container>
Container & sort( Container &container )
{
std::sort( std::begin( container ), std::end( container ) );

return container;
}


bool isAnagrams( std::string s1, std::string s2 )
{
return std::size( s1 ) == std::size( s2 ) and sort( s1 ) == sort( s2 );
}


int main()
{
std::cout << "Enter two strings: ";

std::string s1, s2;

std::cin >> s1 >> s2;

std::cout << "The strings " << std::quoted( s1 )
<< " and " << std::quoted( s2 )
<< " are " << ( isAnagrams( s1, s2 ) ? "" : "not" )
<< " anagrams of each other.\n";
}


Its output might look like

Enter two strings: act tac
The strings "act" and "tac" are anagrams of each other.






втПрМОк, 25 ОюМя 2013 г., 1:05:40 UTC+4 пПльзПватель Vlad from Moscow
Post by Vlad from Moscow
In most cases standard algorithms (and some containers' member functions)
std::sort and std:;reverse are called over a whole container. For example
[code]
std::forward_list<int> f;
// filling the list
f.sort();
// or
f.sort( std::greater<int>() );
std::vector<int> v;
//filling the vector
std::sort( v.begin(), v.end() );
// or
std::sort( v.begin(), v.end(), std::greater<int>() );
[/code]
So I suggest to introduce general functions std::reverse and std::sort
that will accept the reference to a container.
Below a demostrative example that illustrates the proposal
[code]
#include <iostream>
#include <algorithm>
#include <iterator>
#include <functional>
#include <vector>
#include <forward_list>
#include <list>
namespace N1 // std
{
template <typename T>
void reverse( T &c )
{
std::reverse( std::begin( c ), std::end( c ) );
}
template <typename T, typename Allocator>
void reverse( std::forward_list<T, Allocator> &f )
{
f.reverse();
}
template <typename T, typename Allocator>
void reverse( std::list<T, Allocator> &l )
{
l.reverse();
}
template <typename T>
void sort( T &c )
{
std::sort( std::begin( c ), std::end( c ) );
}
template <typename T, typename Allocator>
void sort( std::forward_list<T, Allocator> &f )
{
f.sort();
}
template <typename T, typename Allocator>
void sort( std::list<T, Allocator> &l )
{
l.sort();
}
template <typename T, typename Compare>
void sort( T &c, Compare comp )
{
std::sort( std::begin( c ), std::end( c ), comp );
}
template <typename T, typename Allocator, typename Compare>
void sort( std::forward_list<T, Allocator> &f, Compare comp )
{
f.sort( comp );
}
template <typename T, typename Allocator, typename Compare>
void sort( std::list<T, Allocator> &l, Compare comp )
{
l.sort( comp );
}
} // end of N1
int main()
{
int a[3] = { 1, 2, 3 };
std::forward_list<int> f( std::begin( a ), std::end( a ) );
std::list<int> l( std::begin( a ), std::end( a ) );
std::vector<int> v( std::begin( a ), std::end( a ) );
std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
N1::reverse( a );
N1::reverse( f );
N1::reverse( l );
N1::reverse( v );
std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
N1::sort( a );
N1::sort( f );
N1::sort( l );
N1::sort( v );
std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
N1::sort( a, std::greater<int>() );
N1::sort( f, std::greater<int>() );
N1::sort( l, std::greater<int>() );
N1::sort( v, std::greater<int>() );
std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
}
[/code]
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/126acf7d-4224-4a72-a34d-890d23ce5759%40isocpp.org.
Gašper Ažman
2018-12-01 17:36:14 UTC
Permalink
Vlad,

as Justin already said, Ranges already do all that and more. What you want
is already in C++20.

G

On Fri, Nov 30, 2018 at 3:37 PM 'Vlad from Moscow' via ISO C++ Standard -
Post by 'Vlad from Moscow' via ISO C++ Standard - Future Proposals
I'm sorry.
It would be more correctly to define the function the following way
changing the return type tas it is shown
template <typename Container>
Container & sort( Container &container ) requires requires() { &Container
::sort; }
{
container.sort();
return container;
}
template <typename Container>
Container & sort( Container &container )
{
std::sort( std::begin( container ), std::end( container ) );
return container;
}
Consider for example this question of a beginner as me at Stackoverflow
https://stackoverflow.com/questions/53557881/checking-if-two-strings-are-anagram#
It is required to determine whether two strings are anagrams of each other.
One of approaches is to sort the strings and compare them.
Using the functions above the function that determines whether strings are
anagrams can be written easy.
#include <iostream>
#include <iomanip>
#include <string>
#include <iterator>
#include <algorithm>
template <typename Container>
Container & sort( Container &container ) requires requires() { &Container
::sort; }
{
container.sort();
return container;
}
template <typename Container>
Container & sort( Container &container )
{
std::sort( std::begin( container ), std::end( container ) );
return container;
}
bool isAnagrams( std::string s1, std::string s2 )
{
return std::size( s1 ) == std::size( s2 ) and sort( s1 ) == sort( s2 );
}
int main()
{
std::cout << "Enter two strings: ";
std::string s1, s2;
std::cin >> s1 >> s2;
std::cout << "The strings " << std::quoted( s1 )
<< " and " << std::quoted( s2 )
<< " are " << ( isAnagrams( s1, s2 ) ? "" : "not" )
<< " anagrams of each other.\n";
}
Its output might look like
Enter two strings: act tac
The strings "act" and "tac" are anagrams of each other.
втПрМОк, 25 ОюМя 2013 г., 1:05:40 UTC+4 пПльзПватель Vlad from Moscow
Post by Vlad from Moscow
In most cases standard algorithms (and some containers' member functions)
std::sort and std:;reverse are called over a whole container. For example
[code]
std::forward_list<int> f;
// filling the list
f.sort();
// or
f.sort( std::greater<int>() );
std::vector<int> v;
//filling the vector
std::sort( v.begin(), v.end() );
// or
std::sort( v.begin(), v.end(), std::greater<int>() );
[/code]
So I suggest to introduce general functions std::reverse and std::sort
that will accept the reference to a container.
Below a demostrative example that illustrates the proposal
[code]
#include <iostream>
#include <algorithm>
#include <iterator>
#include <functional>
#include <vector>
#include <forward_list>
#include <list>
namespace N1 // std
{
template <typename T>
void reverse( T &c )
{
std::reverse( std::begin( c ), std::end( c ) );
}
template <typename T, typename Allocator>
void reverse( std::forward_list<T, Allocator> &f )
{
f.reverse();
}
template <typename T, typename Allocator>
void reverse( std::list<T, Allocator> &l )
{
l.reverse();
}
template <typename T>
void sort( T &c )
{
std::sort( std::begin( c ), std::end( c ) );
}
template <typename T, typename Allocator>
void sort( std::forward_list<T, Allocator> &f )
{
f.sort();
}
template <typename T, typename Allocator>
void sort( std::list<T, Allocator> &l )
{
l.sort();
}
template <typename T, typename Compare>
void sort( T &c, Compare comp )
{
std::sort( std::begin( c ), std::end( c ), comp );
}
template <typename T, typename Allocator, typename Compare>
void sort( std::forward_list<T, Allocator> &f, Compare comp )
{
f.sort( comp );
}
template <typename T, typename Allocator, typename Compare>
void sort( std::list<T, Allocator> &l, Compare comp )
{
l.sort( comp );
}
} // end of N1
int main()
{
int a[3] = { 1, 2, 3 };
std::forward_list<int> f( std::begin( a ), std::end( a ) );
std::list<int> l( std::begin( a ), std::end( a ) );
std::vector<int> v( std::begin( a ), std::end( a ) );
std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
N1::reverse( a );
N1::reverse( f );
N1::reverse( l );
N1::reverse( v );
std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
N1::sort( a );
N1::sort( f );
N1::sort( l );
N1::sort( v );
std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
N1::sort( a, std::greater<int>() );
N1::sort( f, std::greater<int>() );
N1::sort( l, std::greater<int>() );
N1::sort( v, std::greater<int>() );
std::cout << "a:\t";
for ( int x : a ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "f:\t";
for ( int x : f ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "l:\t";
for ( int x : l ) std::cout << x << ' ';
std::cout << std::endl;
std::cout << "v:\t";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
}
[/code]
--
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/126acf7d-4224-4a72-a34d-890d23ce5759%40isocpp.org
<https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/126acf7d-4224-4a72-a34d-890d23ce5759%40isocpp.org?utm_medium=email&utm_source=footer>
.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkXQDbTKJpB1HvyhU7%2BDmZXOyNMpJ5MLoC%3DaL-w4cUYSTA%40mail.gmail.com.
Loading...