public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
@ 2019-08-06 15:30 Steve Ellcey
  2019-08-06 20:04 ` Jonathan Wakely
  2019-08-07 15:58 ` Ed Smith-Rowland via libstdc++
  0 siblings, 2 replies; 21+ messages in thread
From: Steve Ellcey @ 2019-08-06 15:30 UTC (permalink / raw)
  To: gcc-patches, 3dw4rd, libstdc++

Ed,

I have run into an ICE that I tracked down to this patch:

commit 02fefffe6b78c4c39169206aa40fb53f367ecba8
Author: emsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Aug 1 15:25:42 2019 +0000

    2019-08-01  Edward Smith-Rowland  <3dw4rd@verizon.net>

            Implement C++20 p0202 - Add Constexpr Modifiers to Functions
            in <algorithm> and <utility> Headers.
            Implement C++20 p1023 - constexpr comparison operators for std::array.


Before I try to create a smaller test example (the current failure happens
when I build https://github.com/llnl/RAJAPerf.git) I was wondering if you
have already seen this ICE:

/extra/sellcey/raja-build-error/RAJAPerf/src/apps/WIP-COUPLE.cpp: In member function 'virtual void rajaperf::apps::COUPLE::runKernel(rajaperf::VariantID)':
/extra/sellcey/raja-build-error/RAJAPerf/src/apps/WIP-COUPLE.cpp:217:1: internal compiler error: Segmentation fault
  217 | } // end namespace rajaperf
      | ^
0xe81ddf crash_signal
	../../gcc/gcc/toplev.c:326
0x968d14 lookup_page_table_entry
	../../gcc/gcc/ggc-page.c:632
0x968d14 ggc_set_mark(void const*)
	../../gcc/gcc/ggc-page.c:1531
0xbfeadf gt_ggc_mx_symtab_node(void*)
	/extra/sellcey/gcc-tot/obj-gcc/gcc/gtype-desc.c:1302
0xd9d2a7 gt_ggc_ma_order
	./gt-passes.h:31
0xd9d2a7 gt_ggc_ma_order
	./gt-passes.h:26
0xb6f49f ggc_mark_root_tab
	../../gcc/gcc/ggc-common.c:77
0xb6f6c3 ggc_mark_roots()
	../../gcc/gcc/ggc-common.c:94
0x9696af ggc_collect()
	../../gcc/gcc/ggc-page.c:2201
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-08-06 15:30 [PATCH 1/3] C++20 constexpr lib part 1/3 Steve Ellcey
@ 2019-08-06 20:04 ` Jonathan Wakely
  2019-08-06 20:30   ` [EXT] " Steve Ellcey
  2019-08-07 15:58 ` Ed Smith-Rowland via libstdc++
  1 sibling, 1 reply; 21+ messages in thread
From: Jonathan Wakely @ 2019-08-06 20:04 UTC (permalink / raw)
  To: Steve Ellcey; +Cc: gcc-patches, 3dw4rd, libstdc++

On 06/08/19 15:30 +0000, Steve Ellcey wrote:
>Ed,
>
>I have run into an ICE that I tracked down to this patch:
>
>commit 02fefffe6b78c4c39169206aa40fb53f367ecba8
>Author: emsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4>
>Date:   Thu Aug 1 15:25:42 2019 +0000
>
>    2019-08-01  Edward Smith-Rowland  <3dw4rd@verizon.net>
>
>            Implement C++20 p0202 - Add Constexpr Modifiers to Functions
>            in <algorithm> and <utility> Headers.
>            Implement C++20 p1023 - constexpr comparison operators for std::array.
>
>
>Before I try to create a smaller test example (the current failure happens
>when I build https://github.com/llnl/RAJAPerf.git) I was wondering if you
>have already seen this ICE:
>
>/extra/sellcey/raja-build-error/RAJAPerf/src/apps/WIP-COUPLE.cpp: In member function 'virtual void rajaperf::apps::COUPLE::runKernel(rajaperf::VariantID)':
>/extra/sellcey/raja-build-error/RAJAPerf/src/apps/WIP-COUPLE.cpp:217:1: internal compiler error: Segmentation fault

The RAJAPerf code appears to be built with -std=gnu++11 which means
Ed's patch should make almost no difference at all. 99% of the patch
has no effect unless compiling with -std=gnu++2a.

I don't see any ICE running the libstdc++ testsuite with -std=gnu++11,
so I have no better suggestion than creating a bugzilla report for the
C++ front-end, with the preprocessed source of WIP-COUPLE.cpp

>  217 | } // end namespace rajaperf
>      | ^
>0xe81ddf crash_signal
>	../../gcc/gcc/toplev.c:326
>0x968d14 lookup_page_table_entry
>	../../gcc/gcc/ggc-page.c:632
>0x968d14 ggc_set_mark(void const*)
>	../../gcc/gcc/ggc-page.c:1531
>0xbfeadf gt_ggc_mx_symtab_node(void*)
>	/extra/sellcey/gcc-tot/obj-gcc/gcc/gtype-desc.c:1302
>0xd9d2a7 gt_ggc_ma_order
>	./gt-passes.h:31
>0xd9d2a7 gt_ggc_ma_order
>	./gt-passes.h:26
>0xb6f49f ggc_mark_root_tab
>	../../gcc/gcc/ggc-common.c:77
>0xb6f6c3 ggc_mark_roots()
>	../../gcc/gcc/ggc-common.c:94
>0x9696af ggc_collect()
>	../../gcc/gcc/ggc-page.c:2201
>Please submit a full bug report,
>with preprocessed source if appropriate.
>Please include the complete backtrace with any bug report.
>See <https://gcc.gnu.org/bugs/> for instructions.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [EXT] Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-08-06 20:04 ` Jonathan Wakely
@ 2019-08-06 20:30   ` Steve Ellcey
  2019-08-06 20:47     ` Marek Polacek
  0 siblings, 1 reply; 21+ messages in thread
From: Steve Ellcey @ 2019-08-06 20:30 UTC (permalink / raw)
  To: jwakely; +Cc: gcc-patches, 3dw4rd, libstdc++

On Tue, 2019-08-06 at 21:04 +0100, Jonathan Wakely wrote:
> 
> The RAJAPerf code appears to be built with -std=gnu++11 which means
> Ed's patch should make almost no difference at all. 99% of the patch
> has no effect unless compiling with -std=gnu++2a.
> 
> I don't see any ICE running the libstdc++ testsuite with -std=gnu++11,
> so I have no better suggestion than creating a bugzilla report for the
> C++ front-end, with the preprocessed source of WIP-COUPLE.cpp

I created a preprocessed file.  Unfortunately when I compile that
preprocessed file with the same options as the unpreprocessed file,
it does not ICE.  I compiled the original file with -save-temps and
that compile no longer gives an ICE.  I hate bugs like this.

Steve Ellcey
sellcey@marvell.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [EXT] Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-08-06 20:30   ` [EXT] " Steve Ellcey
@ 2019-08-06 20:47     ` Marek Polacek
  2019-08-06 21:12       ` Steve Ellcey
  0 siblings, 1 reply; 21+ messages in thread
From: Marek Polacek @ 2019-08-06 20:47 UTC (permalink / raw)
  To: Steve Ellcey; +Cc: jwakely, gcc-patches, 3dw4rd, libstdc++

On Tue, Aug 06, 2019 at 08:30:14PM +0000, Steve Ellcey wrote:
> On Tue, 2019-08-06 at 21:04 +0100, Jonathan Wakely wrote:
> > 
> > The RAJAPerf code appears to be built with -std=gnu++11 which means
> > Ed's patch should make almost no difference at all. 99% of the patch
> > has no effect unless compiling with -std=gnu++2a.
> > 
> > I don't see any ICE running the libstdc++ testsuite with -std=gnu++11,
> > so I have no better suggestion than creating a bugzilla report for the
> > C++ front-end, with the preprocessed source of WIP-COUPLE.cpp
> 
> I created a preprocessed file.  Unfortunately when I compile that
> preprocessed file with the same options as the unpreprocessed file,
> it does not ICE.  I compiled the original file with -save-temps and
> that compile no longer gives an ICE.  I hate bugs like this.

Does -fdirectives-only make any difference?

Marek

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [EXT] Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-08-06 20:47     ` Marek Polacek
@ 2019-08-06 21:12       ` Steve Ellcey
  0 siblings, 0 replies; 21+ messages in thread
From: Steve Ellcey @ 2019-08-06 21:12 UTC (permalink / raw)
  To: polacek; +Cc: gcc-patches, 3dw4rd, jwakely, libstdc++

On Tue, 2019-08-06 at 16:47 -0400, Marek Polacek wrote:
> On Tue, Aug 06, 2019 at 08:30:14PM +0000, Steve Ellcey wrote:
> > On Tue, 2019-08-06 at 21:04 +0100, Jonathan Wakely wrote:
> > > 
> > > The RAJAPerf code appears to be built with -std=gnu++11 which
> > > means
> > > Ed's patch should make almost no difference at all. 99% of the
> > > patch
> > > has no effect unless compiling with -std=gnu++2a.
> > > 
> > > I don't see any ICE running the libstdc++ testsuite with
> > > -std=gnu++11,
> > > so I have no better suggestion than creating a bugzilla report
> > > for the
> > > C++ front-end, with the preprocessed source of WIP-COUPLE.cpp
> > 
> > I created a preprocessed file.  Unfortunately when I compile that
> > preprocessed file with the same options as the unpreprocessed file,
> > it does not ICE.  I compiled the original file with -save-temps and
> > that compile no longer gives an ICE.  I hate bugs like this.
> 
> Does -fdirectives-only make any difference?
> 
> Marek

Nope.  I also looked at the preprocessed file compiled with and without
this patch and the two preprocessed files are identical.  I am thinking
that this patch is triggering some unrelated latent bug.

Steve Ellcey
sellcey@marvell.com

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-08-06 15:30 [PATCH 1/3] C++20 constexpr lib part 1/3 Steve Ellcey
  2019-08-06 20:04 ` Jonathan Wakely
@ 2019-08-07 15:58 ` Ed Smith-Rowland via libstdc++
  1 sibling, 0 replies; 21+ messages in thread
From: Ed Smith-Rowland via libstdc++ @ 2019-08-07 15:58 UTC (permalink / raw)
  To: Steve Ellcey, gcc-patches, libstdc++

On 8/6/19 11:30 AM, Steve Ellcey wrote:
> Ed,
>
> I have run into an ICE that I tracked down to this patch:
>
> commit 02fefffe6b78c4c39169206aa40fb53f367ecba8
> Author: emsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4>
> Date:   Thu Aug 1 15:25:42 2019 +0000
>
>      2019-08-01  Edward Smith-Rowland  <3dw4rd@verizon.net>
>
>              Implement C++20 p0202 - Add Constexpr Modifiers to Functions
>              in <algorithm> and <utility> Headers.
>              Implement C++20 p1023 - constexpr comparison operators for std::array.
>
>
> Before I try to create a smaller test example (the current failure happens
> when I build https://github.com/llnl/RAJAPerf.git) I was wondering if you
> have already seen this ICE:
>
> /extra/sellcey/raja-build-error/RAJAPerf/src/apps/WIP-COUPLE.cpp: In member function 'virtual void rajaperf::apps::COUPLE::runKernel(rajaperf::VariantID)':
> /extra/sellcey/raja-build-error/RAJAPerf/src/apps/WIP-COUPLE.cpp:217:1: internal compiler error: Segmentation fault
>    217 | } // end namespace rajaperf
>        | ^
> 0xe81ddf crash_signal
> 	../../gcc/gcc/toplev.c:326
> 0x968d14 lookup_page_table_entry
> 	../../gcc/gcc/ggc-page.c:632
> 0x968d14 ggc_set_mark(void const*)
> 	../../gcc/gcc/ggc-page.c:1531
> 0xbfeadf gt_ggc_mx_symtab_node(void*)
> 	/extra/sellcey/gcc-tot/obj-gcc/gcc/gtype-desc.c:1302
> 0xd9d2a7 gt_ggc_ma_order
> 	./gt-passes.h:31
> 0xd9d2a7 gt_ggc_ma_order
> 	./gt-passes.h:26
> 0xb6f49f ggc_mark_root_tab
> 	../../gcc/gcc/ggc-common.c:77
> 0xb6f6c3 ggc_mark_roots()
> 	../../gcc/gcc/ggc-common.c:94
> 0x9696af ggc_collect()
> 	../../gcc/gcc/ggc-page.c:2201
> Please submit a full bug report,
> with preprocessed source if appropriate.
> Please include the complete backtrace with any bug report.
> See <https://gcc.gnu.org/bugs/> for instructions.

I've been building C++14 code (and C++17 and C++20 code) with this patch 
for half a year and no ICE.

I don't see how the patch could impact pre C++20 code.

Ed


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-08-01 19:45             ` Jonathan Wakely
@ 2019-08-02  1:04               ` Ed Smith-Rowland via libstdc++
  0 siblings, 0 replies; 21+ messages in thread
From: Ed Smith-Rowland via libstdc++ @ 2019-08-02  1:04 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Ville Voutilainen, libstdc++, gcc-patches

On 8/1/19 3:45 PM, Jonathan Wakely wrote:
> On 01/08/19 11:47 -0400, Ed Smith-Rowland via libstdc++ wrote:
>> On 8/1/19 6:56 AM, Jonathan Wakely wrote:
>>> On 31/07/19 10:50 -0400, Ed Smith-Rowland via libstdc++ wrote:
>>>> Here is the patch for
>>>>
>>>> * Implement C++20 p0202 - Add constexpr Modifiers to Functions in 
>>>> <algorithm> and <utility> Headers.
>>>>
>>>> * Implement C++20 p1023 - constexpr comparison operators for 
>>>> std::array.
>>>>
>>>> Relative to the last effort it is rebased on more recent trunk and 
>>>> I added to <version>.
>>>>
>>>> There's some chance that I'll have to tweak the macros after the 
>>>> draft comes in but I'd like to get this moving.?? I've got other 
>>>> chunks of constexpr lib coming.?? This passes C++20 testing 
>>>> onx86_64-linux.
>>>>
>>>> Ok?
>>>
>>> Calls to the new __memmove and __memcmp functions need to be qualified
>>> with std:: to prevent ADL. I think we should rename those functions,
>>> but that can happen later.
>>
>> IMHO, these concepts are too important to leave as an implementation 
>> detail.
>>
>> I suspect the committee will come crawling back to specify these with 
>> real names.
>>
>> memory_copy, memory_compare, memory_move for C++23 anyone?
>
> trivial_copy, trivial_compare, trivial_move

Works for me. I'm sure there will be great bikeshed battles!

Ed


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-08-01 15:47           ` Ed Smith-Rowland via libstdc++
@ 2019-08-01 19:45             ` Jonathan Wakely
  2019-08-02  1:04               ` Ed Smith-Rowland via libstdc++
  0 siblings, 1 reply; 21+ messages in thread
From: Jonathan Wakely @ 2019-08-01 19:45 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: Ville Voutilainen, libstdc++, gcc-patches

On 01/08/19 11:47 -0400, Ed Smith-Rowland via libstdc++ wrote:
>On 8/1/19 6:56 AM, Jonathan Wakely wrote:
>>On 31/07/19 10:50 -0400, Ed Smith-Rowland via libstdc++ wrote:
>>>Here is the patch for
>>>
>>>* Implement C++20 p0202 - Add constexpr Modifiers to Functions in 
>>><algorithm> and <utility> Headers.
>>>
>>>* Implement C++20 p1023 - constexpr comparison operators for std::array.
>>>
>>>Relative to the last effort it is rebased on more recent trunk and 
>>>I added to <version>.
>>>
>>>There's some chance that I'll have to tweak the macros after the 
>>>draft comes in but I'd like to get this moving.?? I've got other 
>>>chunks of constexpr lib coming.?? This passes C++20 testing 
>>>onx86_64-linux.
>>>
>>>Ok?
>>
>>Calls to the new __memmove and __memcmp functions need to be qualified
>>with std:: to prevent ADL. I think we should rename those functions,
>>but that can happen later.
>
>IMHO, these concepts are too important to leave as an implementation detail.
>
>I suspect the committee will come crawling back to specify these with 
>real names.
>
>memory_copy, memory_compare, memory_move for C++23 anyone?

trivial_copy, trivial_compare, trivial_move?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-08-01 10:56         ` Jonathan Wakely
@ 2019-08-01 15:47           ` Ed Smith-Rowland via libstdc++
  2019-08-01 19:45             ` Jonathan Wakely
  0 siblings, 1 reply; 21+ messages in thread
From: Ed Smith-Rowland via libstdc++ @ 2019-08-01 15:47 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Ville Voutilainen, libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2208 bytes --]

On 8/1/19 6:56 AM, Jonathan Wakely wrote:
> On 31/07/19 10:50 -0400, Ed Smith-Rowland via libstdc++ wrote:
>> Here is the patch for
>>
>> * Implement C++20 p0202 - Add constexpr Modifiers to Functions in 
>> <algorithm> and <utility> Headers.
>>
>> * Implement C++20 p1023 - constexpr comparison operators for std::array.
>>
>> Relative to the last effort it is rebased on more recent trunk and I 
>> added to <version>.
>>
>> There's some chance that I'll have to tweak the macros after the 
>> draft comes in but I'd like to get this moving.?? I've got other 
>> chunks of constexpr lib coming.?? This passes C++20 testing 
>> onx86_64-linux.
>>
>> Ok?
>
> Calls to the new __memmove and __memcmp functions need to be qualified
> with std:: to prevent ADL. I think we should rename those functions,
> but that can happen later.

IMHO, these concepts are too important to leave as an implementation detail.

I suspect the committee will come crawling back to specify these with 
real names.

memory_copy, memory_compare, memory_move for C++23 anyone?

> The new 23_containers/array/comparison_operators/constexpr.cc test
> will be UNSUPPORTED by default because it doesn't have the directive
> { dg-options "-std=gnu++2a" }.
>
> The change to the <version> header defines __cpp_lib_constexpr instead
> of __cpp_lib_constexpr_algorithms as it should be. For some recent
> changes I've added a testcase that does nothing but include <version>
> and check the feature test macro, which ensures that it's set
> correctly by <version> not just by the other header(s) defining it.
> For example, see testsuite/26_numerics/numbers/2.cc added yesterday.
I'll add a testcase.
> I wonder if the feature test macro should only be defined when
> __cpp_lib_is_constant_evaluated is defined, because otherwise some
> algos will not be usable constant expressions (e.g. when compiled with
> Clang 7.0).
We can do this later if we need to.
>
> OK for trunk with:
>
> - std:: qualification on the new __mem* functions;
Done.
> - the dg-options added to the testcase;
Done.
> - fix the macro in <version> (and ideally add a test for it).
Done.
> Thanks.

Committed with 273975.?? Final patch and CL attached.

Regards,

Ed



[-- Attachment #2: CL_constexpr_lib --]
[-- Type: text/plain, Size: 7208 bytes --]

2019-08-01  Edward Smith-Rowland  <3dw4rd@verizon.net>

	Implement C++20 p0202 - Add Constexpr Modifiers to Functions
	in <algorithm> and <utility> Headers.
	Implement C++20 p1023 - constexpr comparison operators for std::array.
	* include/bits/algorithmfwd.h (all_of, any_of, binary_search, copy,
	copy_backward, copy_if, copy_n, equal_range, fill, find_end,
	find_if_not, includes, is_heap, is_heap_until, is_partitioned,
	is_permutation, is_sorted, is_sorted_until, iter_swap, lower_bound,
	none_of, partition_copy, partition_point, remove, remove_if,
	remove_copy, remove_copy_if, replace_copy, replace_copy_if,
	reverse_copy, rotate_copy, uunique, upper_bound, adjacent_find, count,
	count_if, equal, find, find_first_of, find_if, for_each, generate,
	generate_n, lexicographical_compare, merge, mismatch, replace,
	replace_if, search, search_n, set_difference, set_intersection,
	set_symmetric_difference, set_union, transform, unique_copy):
	Mark constexpr.
	* include/bits/cpp_type_traits.h (__miter_base): Mark constexpr.
	* include/bits/predefined_ops.h (_Iter_less_val::operator(),
	_Val_less_iter::operator(), _Iter_equal_to_iter::operator(),
	_Iter_equal_to_val::operator(), _Iter_equals_val::operator()):
	 Use const ref instead of ref arg;
	(_Iter_less_val, __iter_less_val, _Val_less_iter, __val_less_iter,
	__iter_equal_to_iter, __iter_equal_to_val, __iter_comp_val,
	_Iter_comp_val, _Val_comp_iter, __val_comp_iter, __iter_equals_val,
	_Iter_equals_iter, __iter_comp_iter, _Iter_pred, __pred_iter,
	_Iter_comp_to_val, __iter_comp_val, _Iter_comp_to_iter,
	__iter_comp_iter): Mark constexpr.
	* include/bits/stl_algo.h (__find_if, __find_if_not, __find_if_not_n,
	__search, __search_n_aux, __search_n, __find_end, find_end, all_of,
	none_of, any_of, find_if_not, is_partitioned, partition_point,
	__remove_copy_if, remove_copy, remove_copy_if, copy_if, __copy_n,
	copy_n, partition_copy, __remove_if, remove, remove_if, __adjacent_find,
	__unique, unique, __unique_copy, reverse_copy, rotate_copy,
	__unguarded_linear_insert, __insertion_sort, __unguarded_insertion_sort,
	__final_insertion_sort, lower_bound, __upper_bound, upper_bound,
	__equal_range, equal_range, binary_search, __includes, includes,
	__next_permutation, __prev_permutation, __replace_copy_if, replace_copy,
	replace_copy_if, __count_if, is_sorted, __is_sorted_until,
	is_sorted_until, __is_permutation, is_permutation, for_each, find,
	find_if, find_first_of, adjacent_find, count, count_if, search,
	search_n, transform, replace, replace_if, generate, generate_n,
	unique_copy, __merge, merge, __set_union, set_union, __set_intersection,
	set_intersection, __set_difference, set_difference,
	__set_symmetric_difference, set_symmetric_difference):  Mark constexpr.
	* include/bits/stl_algobase.h (__memmove, __memcmp): New maybe constexpr
	wrappers around __builtin_memmove and __builtin_memcmp
	respectively;
	(__niter_base, __niter_wrap, __copy_m, __copy_move_a, __copy_move_a2,
	copy, move, __copy_move_b, __copy_move_backward_a,
	__copy_move_backward_a2, copy_backward, move_backward, __fill_a, fill,
	__fill_n_a, fill_n, equal, __lc_rai::__newlast1, __lc_rai::__cnd2,
	__lexicographical_compare_impl, __lexicographical_compare,
	__lexicographical_compare<true>::__lc, __lexicographical_compare_aux,
	__lower_bound, lower_bound, equal, __equal4, lexicographical_compare,
	__mismatch, mismatch, __is_heap_until, __is_heap, is_heap_until,
	is_heap): Mark constexpr.
	* include/bits/stl_heap.h (__is_heap_until, __is_heap, is_heap_until,
	is_heap): Mark constexpr.
	* include/bits/stl_iterator.h (__niter_base, __miter_base): Mark constexpr.
	* include/std/array: Make comparison ops constexpr.
	* include/std/utility: Make exchange constexpr.
	* include/std/version (__cpp_lib_constexpr_algorithms): New macro.
	* testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust.
	* testsuite/23_containers/array/tuple_interface/
	tuple_element_neg.cc: Adjust.
	* testsuite/20_util/exchange/constexpr.cc: New.
	* testsuite/23_containers/array/comparison_operators/constexpr.cc: New.
	* testsuite/25_algorithms/constexpr_macro.cc: New.
	* testsuite/25_algorithms/adjacent_find/constexpr.cc: New.
	* testsuite/25_algorithms/all_of/constexpr.cc: New.
	* testsuite/25_algorithms/any_of/constexpr.cc: New.
	* testsuite/25_algorithms/binary_search/constexpr.cc: New.
	* testsuite/25_algorithms/copy/constexpr.cc: New.
	* testsuite/25_algorithms/copy_backward/constexpr.cc: New.
	* testsuite/25_algorithms/copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/copy_n/constexpr.cc: New.
	* testsuite/25_algorithms/count/constexpr.cc: New.
	* testsuite/25_algorithms/count_if/constexpr.cc: New.
	* testsuite/25_algorithms/equal/constexpr.cc: New.
	* testsuite/25_algorithms/equal_range/constexpr.cc: New.
	* testsuite/25_algorithms/fill/constexpr.cc: New.
	* testsuite/25_algorithms/fill_n/constexpr.cc: New.
	* testsuite/25_algorithms/find/constexpr.cc: New.
	* testsuite/25_algorithms/find_end/constexpr.cc: New.
	* testsuite/25_algorithms/find_first_of/constexpr.cc: New.
	* testsuite/25_algorithms/find_if/constexpr.cc: New.
	* testsuite/25_algorithms/find_if_not/constexpr.cc: New.
	* testsuite/25_algorithms/for_each/constexpr.cc: New.
	* testsuite/25_algorithms/generate/constexpr.cc: New.
	* testsuite/25_algorithms/generate_n/constexpr.cc: New.
	* testsuite/25_algorithms/is_heap/constexpr.cc: New.
	* testsuite/25_algorithms/is_heap_until/constexpr.cc: New.
	* testsuite/25_algorithms/is_partitioned/constexpr.cc: New.
	* testsuite/25_algorithms/is_permutation/constexpr.cc: New.
	* testsuite/25_algorithms/is_sorted/constexpr.cc: New.
	* testsuite/25_algorithms/is_sorted_until/constexpr.cc: New.
	* testsuite/25_algorithms/lexicographical_compare/constexpr.cc: New.
	* testsuite/25_algorithms/lower_bound/constexpr.cc: New.
	* testsuite/25_algorithms/merge/constexpr.cc: New.
	* testsuite/25_algorithms/mismatch/constexpr.cc: New.
	* testsuite/25_algorithms/none_of/constexpr.cc: New.
	* testsuite/25_algorithms/partition_copy/constexpr.cc: New.
	* testsuite/25_algorithms/partition_point/constexpr.cc: New.
	* testsuite/25_algorithms/remove/constexpr.cc: New.
	* testsuite/25_algorithms/remove_copy/constexpr.cc: New.
	* testsuite/25_algorithms/remove_copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/remove_if/constexpr.cc: New.
	* testsuite/25_algorithms/replace_copy/constexpr.cc: New.
	* testsuite/25_algorithms/replace_copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/replace_if/constexpr.cc: New.
	* testsuite/25_algorithms/reverse_copy/constexpr.cc: New.
	* testsuite/25_algorithms/rotate_copy/constexpr.cc: New.
	* testsuite/25_algorithms/search/constexpr.cc: New.
	* testsuite/25_algorithms/search_n/constexpr.cc: New.
	* testsuite/25_algorithms/set_difference/constexpr.cc: New.
	* testsuite/25_algorithms/set_intersection/constexpr.cc: New.
	* testsuite/25_algorithms/set_symmetric_difference/constexpr.cc: New.
	* testsuite/25_algorithms/set_union/constexpr.cc: New.
	* testsuite/25_algorithms/transform/constexpr.cc: New.
	* testsuite/25_algorithms/unique/constexpr.cc: New.
	* testsuite/25_algorithms/unique_copy/constexpr.cc: New.
	* testsuite/25_algorithms/upper_bound/constexpr.cc: New.

[-- Attachment #3: patch_constexpr_lib_4.bz2 --]
[-- Type: application/x-bzip, Size: 15133 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-07-31 14:50       ` Ed Smith-Rowland via libstdc++
@ 2019-08-01 10:56         ` Jonathan Wakely
  2019-08-01 15:47           ` Ed Smith-Rowland via libstdc++
  0 siblings, 1 reply; 21+ messages in thread
From: Jonathan Wakely @ 2019-08-01 10:56 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: Ville Voutilainen, libstdc++, gcc-patches

On 31/07/19 10:50 -0400, Ed Smith-Rowland via libstdc++ wrote:
>Here is the patch for
>
>* Implement C++20 p0202 - Add constexpr Modifiers to Functions in 
><algorithm> and <utility> Headers.
>
>* Implement C++20 p1023 - constexpr comparison operators for std::array.
>
>Relative to the last effort it is rebased on more recent trunk and I 
>added to <version>.
>
>There's some chance that I'll have to tweak the macros after the draft 
>comes in but I'd like to get this moving.?? I've got other chunks of 
>constexpr lib coming.?? This passes C++20 testing onx86_64-linux.
>
>Ok?

Calls to the new __memmove and __memcmp functions need to be qualified
with std:: to prevent ADL. I think we should rename those functions,
but that can happen later.

The new 23_containers/array/comparison_operators/constexpr.cc test
will be UNSUPPORTED by default because it doesn't have the directive
{ dg-options "-std=gnu++2a" }.

The change to the <version> header defines __cpp_lib_constexpr instead
of __cpp_lib_constexpr_algorithms as it should be. For some recent
changes I've added a testcase that does nothing but include <version>
and check the feature test macro, which ensures that it's set
correctly by <version> not just by the other header(s) defining it.
For example, see testsuite/26_numerics/numbers/2.cc added yesterday.

I wonder if the feature test macro should only be defined when
__cpp_lib_is_constant_evaluated is defined, because otherwise some
algos will not be usable constant expressions (e.g. when compiled with
Clang 7.0).

OK for trunk with:

- std:: qualification on the new __mem* functions;
- the dg-options added to the testcase;
- fix the macro in <version> (and ideally add a test for it).

Thanks.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-07-06  7:55     ` Ville Voutilainen
  2019-07-11 16:40       ` Ed Smith-Rowland via libstdc++
@ 2019-07-31 14:50       ` Ed Smith-Rowland via libstdc++
  2019-08-01 10:56         ` Jonathan Wakely
  1 sibling, 1 reply; 21+ messages in thread
From: Ed Smith-Rowland via libstdc++ @ 2019-07-31 14:50 UTC (permalink / raw)
  To: Ville Voutilainen; +Cc: Jonathan Wakely, libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 506 bytes --]

Here is the patch for

* Implement C++20 p0202 - Add constexpr Modifiers to Functions in 
<algorithm> and <utility> Headers.

* Implement C++20 p1023 - constexpr comparison operators for std::array.

Relative to the last effort it is rebased on more recent trunk and I 
added to <version>.

There's some chance that I'll have to tweak the macros after the draft 
comes in but I'd like to get this moving.?? I've got other chunks of 
constexpr lib coming.?? This passes C++20 testing onx86_64-linux.

Ok?



[-- Attachment #2: CL_constexpr_lib --]
[-- Type: text/plain, Size: 7145 bytes --]

2019-07-31  Edward Smith-Rowland  <3dw4rd@verizon.net>

	Implement C++20 p0202 - Add Constexpr Modifiers to Functions
	in <algorithm> and <utility> Headers.
	Implement C++20 p1023 - constexpr comparison operators for std::array.
	* include/bits/algorithmfwd.h (all_of, any_of, binary_search, copy,
	copy_backward, copy_if, copy_n, equal_range, fill, find_end,
	find_if_not, includes, is_heap, is_heap_until, is_partitioned,
	is_permutation, is_sorted, is_sorted_until, iter_swap, lower_bound,
	none_of, partition_copy, partition_point, remove, remove_if,
	remove_copy, remove_copy_if, replace_copy, replace_copy_if,
	reverse_copy, rotate_copy, uunique, upper_bound, adjacent_find, count,
	count_if, equal, find, find_first_of, find_if, for_each, generate,
	generate_n, lexicographical_compare, merge, mismatch, replace,
	replace_if, search, search_n, set_difference, set_intersection,
	set_symmetric_difference, set_union, transform, unique_copy):
	Mark constexpr.
	* include/bits/cpp_type_traits.h (__miter_base): Mark constexpr.
	* include/bits/predefined_ops.h (_Iter_less_val::operator(),
	_Val_less_iter::operator(), _Iter_equal_to_iter::operator(),
	_Iter_equal_to_val::operator(), _Iter_equals_val::operator()):
	 Use const ref instead of ref arg;
	(_Iter_less_val, __iter_less_val, _Val_less_iter, __val_less_iter,
	__iter_equal_to_iter, __iter_equal_to_val, __iter_comp_val,
	_Iter_comp_val, _Val_comp_iter, __val_comp_iter, __iter_equals_val,
	_Iter_equals_iter, __iter_comp_iter, _Iter_pred, __pred_iter,
	_Iter_comp_to_val, __iter_comp_val, _Iter_comp_to_iter,
	__iter_comp_iter): Mark constexpr.
	* include/bits/stl_algo.h (__find_if, __find_if_not, __find_if_not_n,
	__search, __search_n_aux, __search_n, __find_end, find_end, all_of,
	none_of, any_of, find_if_not, is_partitioned, partition_point,
	__remove_copy_if, remove_copy, remove_copy_if, copy_if, __copy_n,
	copy_n, partition_copy, __remove_if, remove, remove_if, __adjacent_find,
	__unique, unique, __unique_copy, reverse_copy, rotate_copy,
	__unguarded_linear_insert, __insertion_sort, __unguarded_insertion_sort,
	__final_insertion_sort, lower_bound, __upper_bound, upper_bound,
	__equal_range, equal_range, binary_search, __includes, includes,
	__next_permutation, __prev_permutation, __replace_copy_if, replace_copy,
	replace_copy_if, __count_if, is_sorted, __is_sorted_until,
	is_sorted_until, __is_permutation, is_permutation, for_each, find,
	find_if, find_first_of, adjacent_find, count, count_if, search,
	search_n, transform, replace, replace_if, generate, generate_n,
	unique_copy, __merge, merge, __set_union, set_union, __set_intersection,
	set_intersection, __set_difference, set_difference,
	__set_symmetric_difference, set_symmetric_difference):  Mark constexpr.
	* include/bits/stl_algobase.h (__memmove, __memcmp): New maybe constexpr
	wrappers around __builtin_memmove and __builtin_memcmp
	respectively;
	(__niter_base, __niter_wrap, __copy_m, __copy_move_a, __copy_move_a2,
	copy, move, __copy_move_b, __copy_move_backward_a,
	__copy_move_backward_a2, copy_backward, move_backward, __fill_a, fill,
	__fill_n_a, fill_n, equal, __lc_rai::__newlast1, __lc_rai::__cnd2,
	__lexicographical_compare_impl, __lexicographical_compare,
	__lexicographical_compare<true>::__lc, __lexicographical_compare_aux,
	__lower_bound, lower_bound, equal, __equal4, lexicographical_compare,
	__mismatch, mismatch, __is_heap_until, __is_heap, is_heap_until,
	is_heap): Mark constexpr.
	* include/bits/stl_heap.h (__is_heap_until, __is_heap, is_heap_until,
	is_heap): Mark constexpr.
	* include/bits/stl_iterator.h (__niter_base, __miter_base): Mark constexpr.
	* include/std/array: Make comparison ops constexpr.
	* include/std/utility: Make exchange constexpr.
	* include/std/version (__cpp_lib_constexpr): New macro.
	* testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust.
	* testsuite/23_containers/array/tuple_interface/
	tuple_element_neg.cc: Adjust.
	* testsuite/20_util/exchange/constexpr.cc: New.
	* testsuite/23_containers/array/comparison_operators/constexpr.cc: New.
	* testsuite/25_algorithms/adjacent_find/constexpr.cc: New.
	* testsuite/25_algorithms/all_of/constexpr.cc: New.
	* testsuite/25_algorithms/any_of/constexpr.cc: New.
	* testsuite/25_algorithms/binary_search/constexpr.cc: New.
	* testsuite/25_algorithms/copy/constexpr.cc: New.
	* testsuite/25_algorithms/copy_backward/constexpr.cc: New.
	* testsuite/25_algorithms/copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/copy_n/constexpr.cc: New.
	* testsuite/25_algorithms/count/constexpr.cc: New.
	* testsuite/25_algorithms/count_if/constexpr.cc: New.
	* testsuite/25_algorithms/equal/constexpr.cc: New.
	* testsuite/25_algorithms/equal_range/constexpr.cc: New.
	* testsuite/25_algorithms/fill/constexpr.cc: New.
	* testsuite/25_algorithms/fill_n/constexpr.cc: New.
	* testsuite/25_algorithms/find/constexpr.cc: New.
	* testsuite/25_algorithms/find_end/constexpr.cc: New.
	* testsuite/25_algorithms/find_first_of/constexpr.cc: New.
	* testsuite/25_algorithms/find_if/constexpr.cc: New.
	* testsuite/25_algorithms/find_if_not/constexpr.cc: New.
	* testsuite/25_algorithms/for_each/constexpr.cc: New.
	* testsuite/25_algorithms/generate/constexpr.cc: New.
	* testsuite/25_algorithms/generate_n/constexpr.cc: New.
	* testsuite/25_algorithms/is_heap/constexpr.cc: New.
	* testsuite/25_algorithms/is_heap_until/constexpr.cc: New.
	* testsuite/25_algorithms/is_partitioned/constexpr.cc: New.
	* testsuite/25_algorithms/is_permutation/constexpr.cc: New.
	* testsuite/25_algorithms/is_sorted/constexpr.cc: New.
	* testsuite/25_algorithms/is_sorted_until/constexpr.cc: New.
	* testsuite/25_algorithms/lexicographical_compare/constexpr.cc: New.
	* testsuite/25_algorithms/lower_bound/constexpr.cc: New.
	* testsuite/25_algorithms/merge/constexpr.cc: New.
	* testsuite/25_algorithms/mismatch/constexpr.cc: New.
	* testsuite/25_algorithms/none_of/constexpr.cc: New.
	* testsuite/25_algorithms/partition_copy/constexpr.cc: New.
	* testsuite/25_algorithms/partition_point/constexpr.cc: New.
	* testsuite/25_algorithms/remove/constexpr.cc: New.
	* testsuite/25_algorithms/remove_copy/constexpr.cc: New.
	* testsuite/25_algorithms/remove_copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/remove_if/constexpr.cc: New.
	* testsuite/25_algorithms/replace_copy/constexpr.cc: New.
	* testsuite/25_algorithms/replace_copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/replace_if/constexpr.cc: New.
	* testsuite/25_algorithms/reverse_copy/constexpr.cc: New.
	* testsuite/25_algorithms/rotate_copy/constexpr.cc: New.
	* testsuite/25_algorithms/search/constexpr.cc: New.
	* testsuite/25_algorithms/search_n/constexpr.cc: New.
	* testsuite/25_algorithms/set_difference/constexpr.cc: New.
	* testsuite/25_algorithms/set_intersection/constexpr.cc: New.
	* testsuite/25_algorithms/set_symmetric_difference/constexpr.cc: New.
	* testsuite/25_algorithms/set_union/constexpr.cc: New.
	* testsuite/25_algorithms/transform/constexpr.cc: New.
	* testsuite/25_algorithms/unique/constexpr.cc: New.
	* testsuite/25_algorithms/unique_copy/constexpr.cc: New.
	* testsuite/25_algorithms/upper_bound/constexpr.cc: New.

[-- Attachment #3: patch_constexpr_lib_3.bz2 --]
[-- Type: application/x-bzip, Size: 15017 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-07-06  7:55     ` Ville Voutilainen
@ 2019-07-11 16:40       ` Ed Smith-Rowland via libstdc++
  2019-07-31 14:50       ` Ed Smith-Rowland via libstdc++
  1 sibling, 0 replies; 21+ messages in thread
From: Ed Smith-Rowland via libstdc++ @ 2019-07-11 16:40 UTC (permalink / raw)
  To: Ville Voutilainen; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On 7/6/19 3:55 AM, Ville Voutilainen wrote:
>> Blargh!
> But that's fine; the result of copy is not stored in a constexpr
> variable, but the function return
> is static_asserted so we have sufficiently tested that std::copy is
> indeed constexpr-compatible
> since it appears in a function that is evaluated at compile-time.

Ping?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-07-06  3:11   ` Ed Smith-Rowland via libstdc++
@ 2019-07-06  7:55     ` Ville Voutilainen
  2019-07-11 16:40       ` Ed Smith-Rowland via libstdc++
  2019-07-31 14:50       ` Ed Smith-Rowland via libstdc++
  0 siblings, 2 replies; 21+ messages in thread
From: Ville Voutilainen @ 2019-07-06  7:55 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On Sat, 6 Jul 2019 at 06:12, Ed Smith-Rowland via libstdc++
<libstdc++@gcc.gnu.org> wrote:
> By my reckoning, you have a constexpr source array, an output array that
> is initialized as it must be for constexpr.?? You have to have a
> deterministic result after the copy.?? In the local array version the
> actual iterator is not leaking out - just the results of a calculation
> that must return one result.
>
> The only thing that 'helps' is removing the constexpr from the iterator
> return and of course that's the whole point of the thing.
>
> Blargh!

But that's fine; the result of copy is not stored in a constexpr
variable, but the function return
is static_asserted so we have sufficiently tested that std::copy is
indeed constexpr-compatible
since it appears in a function that is evaluated at compile-time.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-07-02 12:11 ` Jonathan Wakely
@ 2019-07-06  3:11   ` Ed Smith-Rowland via libstdc++
  2019-07-06  7:55     ` Ville Voutilainen
  0 siblings, 1 reply; 21+ messages in thread
From: Ed Smith-Rowland via libstdc++ @ 2019-07-06  3:11 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 4055 bytes --]

On 7/2/19 8:11 AM, Jonathan Wakely wrote:
> One more comment. In <bits/stl_algobase.h> this:
>
> +#if __cplusplus > 201703L \
> +?????? && defined(_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED)
> +?????????? if (__builtin_is_constant_evaluated())
>
> can be simplified to just:
>
> #ifdef __cpp_lib_is_constant_evaluated
> ???????? if (std::is_constant_evaluated())
>
> The feature test macro is exactly the check we want here

This is done and the test cases for the non-modifying algorithms are done.

I'm was stumped on the modifying algos though.?? Consider std::copy:

-------------------------------------

constexpr bool
test()
{
 ?? constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
11}};
 ?? std::array<int, 12> ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};

 ?? constexpr auto out6 = std::copy(ca0.begin(), ca0.begin() + 8, 
ma0.begin() + 2);

 ?? return out6 == ma0.begin() + 10;
}

static_assert(test());
-------------------------------------

This is essentially the same as the Boost test case referenced in p0202.

I've also taken the arrays out as globals with the same result either way:

-------------------------------------

ed@bad-horse:~/cxx_constexpr_lib$ ../bin_constexpr_lib/bin/g++ 
-std=gnu++2a -c testsuite/25_algorithms/copy/constexpr.cc
testsuite/25_algorithms/copy/constexpr.cc: In function ???constexpr bool 
test()???:
testsuite/25_algorithms/copy/constexpr.cc:36:34:???? in ???constexpr??? 
expansion of ???std::copy<const int*, int*>(ca0.std::array<int, 
12>::begin(), (ca0.std::array<int, 12>::begin() + 32), 
(ma0.std::array<int, 12>::begin() + 8))???
/home/ed/bin_constexpr_lib/include/c++/10.0.0/bits/stl_algobase.h:535:7: 
in ???constexpr??? expansion of ???std::__copy_move_a2<false, const int*, 
int*>(std::__miter_base<const int*>(__first), std::__miter_base<const 
int*>(__last), __result)???
/home/ed/bin_constexpr_lib/include/c++/10.0.0/bits/stl_algobase.h:501:30: 
in ???constexpr??? expansion of ???std::__copy_move_a<false, const int*, 
int*>(std::__niter_base<const int*>(__first), std::__niter_base<const 
int*>(__last), std::__niter_base<int*>(__result))???
/home/ed/bin_constexpr_lib/include/c++/10.0.0/bits/stl_algobase.h:463:30: 
in ???constexpr??? expansion of ???std::__copy_move<false, true, 
std::random_access_iterator_tag>::__copy_m<int>(__first, __last, __result)???
/home/ed/bin_constexpr_lib/include/c++/10.0.0/bits/stl_algobase.h:445:24: 
in ???constexpr??? expansion of ???std::__memmove<false, int>(__result, 
__first, ((std::size_t)((std::ptrdiff_t)_Num)))???
testsuite/25_algorithms/copy/constexpr.cc:36:80: error: modification of 
???ma0??? is not a constant expression
 ???? 36 |???? constexpr auto out6 = std::copy(ca0.begin(), ca0.begin() + 8, 
ma0.begin() + 2);
| ^
testsuite/25_algorithms/copy/constexpr.cc: At global scope:
testsuite/25_algorithms/copy/constexpr.cc:41:19: error: non-constant 
condition for static assertion
 ???? 41 | static_assert(test());
 ?????????? |???????????????????????????? ~~~~^~

-------------------------------------

By my reckoning, you have a constexpr source array, an output array that 
is initialized as it must be for constexpr.?? You have to have a 
deterministic result after the copy.?? In the local array version the 
actual iterator is not leaking out - just the results of a calculation 
that must return one result.

The only thing that 'helps' is removing the constexpr from the iterator 
return and of course that's the whole point of the thing.

Blargh!

So, you can't modify a constexpr sequence. No actual surprise.?? The 
returned iterators into non-constexpr sequences can never be literals.?? 
What you *can* do is make the modifying algorithms so you can make pure 
functions with them.?? In this connection my previous testcases for 
non-modifying?? were correct, just not complete because there the 
returned iterators into constexpr sequences can be (must be) literals.

So here is a new patch for chunk 1 of constexpr library.

Tested with default settings and with -std=gnu++2a on x86_64-linux.

OK?

Ed



[-- Attachment #2: CL_constexpr_lib --]
[-- Type: text/plain, Size: 7088 bytes --]

2019-07-08  Edward Smith-Rowland  <3dw4rd@verizon.net>

	Implement C++20 p0202 - Add Constexpr Modifiers to Functions
	in <algorithm> and <utility> Headers.
	Implement C++20 p1023 - constexpr comparison operators for std::array.
	* include/bits/algorithmfwd.h (all_of, any_of, binary_search, copy,
	copy_backward, copy_if, copy_n, equal_range, fill, find_end,
	find_if_not, includes, is_heap, is_heap_until, is_partitioned,
	is_permutation, is_sorted, is_sorted_until, iter_swap, lower_bound,
	none_of, partition_copy, partition_point, remove, remove_if,
	remove_copy, remove_copy_if, replace_copy, replace_copy_if,
	reverse_copy, rotate_copy, uunique, upper_bound, adjacent_find, count,
	count_if, equal, find, find_first_of, find_if, for_each, generate,
	generate_n, lexicographical_compare, merge, mismatch, replace,
	replace_if, search, search_n, set_difference, set_intersection,
	set_symmetric_difference, set_union, transform, unique_copy):
	Mark constexpr.
	* include/bits/cpp_type_traits.h (__miter_base): Mark constexpr.
	* include/bits/predefined_ops.h (_Iter_less_val::operator(),
	_Val_less_iter::operator(), _Iter_equal_to_iter::operator(),
	_Iter_equal_to_val::operator(), _Iter_equals_val::operator()):
	 Use const ref instead of ref arg;
	(_Iter_less_val, __iter_less_val, _Val_less_iter, __val_less_iter,
	__iter_equal_to_iter, __iter_equal_to_val, __iter_comp_val,
	_Iter_comp_val, _Val_comp_iter, __val_comp_iter, __iter_equals_val,
	_Iter_equals_iter, __iter_comp_iter, _Iter_pred, __pred_iter,
	_Iter_comp_to_val, __iter_comp_val, _Iter_comp_to_iter,
	__iter_comp_iter): Mark constexpr.
	* include/bits/stl_algo.h (__find_if, __find_if_not, __find_if_not_n,
	__search, __search_n_aux, __search_n, __find_end, find_end, all_of,
	none_of, any_of, find_if_not, is_partitioned, partition_point,
	__remove_copy_if, remove_copy, remove_copy_if, copy_if, __copy_n,
	copy_n, partition_copy, __remove_if, remove, remove_if, __adjacent_find,
	__unique, unique, __unique_copy, reverse_copy, rotate_copy,
	__unguarded_linear_insert, __insertion_sort, __unguarded_insertion_sort,
	__final_insertion_sort, lower_bound, __upper_bound, upper_bound,
	__equal_range, equal_range, binary_search, __includes, includes,
	__next_permutation, __prev_permutation, __replace_copy_if, replace_copy,
	replace_copy_if, __count_if, is_sorted, __is_sorted_until,
	is_sorted_until, __is_permutation, is_permutation, for_each, find,
	find_if, find_first_of, adjacent_find, count, count_if, search,
	search_n, transform, replace, replace_if, generate, generate_n,
	unique_copy, __merge, merge, __set_union, set_union, __set_intersection,
	set_intersection, __set_difference, set_difference,
	__set_symmetric_difference, set_symmetric_difference):  Mark constexpr.
	* include/bits/stl_algobase.h (__memmove, __memcmp): New maybe constexpr
	wrappers around __builtin_memmove and __builtin_memcmp
	respectively;
	(__niter_base, __niter_wrap, __copy_m, __copy_move_a, __copy_move_a2,
	copy, move, __copy_move_b, __copy_move_backward_a,
	__copy_move_backward_a2, copy_backward, move_backward, __fill_a, fill,
	__fill_n_a, fill_n, equal, __lc_rai::__newlast1, __lc_rai::__cnd2,
	__lexicographical_compare_impl, __lexicographical_compare,
	__lexicographical_compare<true>::__lc, __lexicographical_compare_aux,
	__lower_bound, lower_bound, equal, __equal4, lexicographical_compare,
	__mismatch, mismatch, __is_heap_until, __is_heap, is_heap_until,
	is_heap): Mark constexpr.
	* include/bits/stl_heap.h (__is_heap_until, __is_heap, is_heap_until,
	is_heap): Mark constexpr.
	* include/bits/stl_iterator.h (__niter_base, __miter_base): Mark constexpr.
	* include/std/array: Make comparison ops constexpr.
	* include/std/utility: Make exchange constexpr.
	* testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust.
	* testsuite/23_containers/array/tuple_interface/
	tuple_element_neg.cc: Adjust.
	* testsuite/20_util/exchange/constexpr.cc: New.
	* testsuite/23_containers/array/comparison_operators/constexpr.cc: New.
	* testsuite/25_algorithms/adjacent_find/constexpr.cc: New.
	* testsuite/25_algorithms/all_of/constexpr.cc: New.
	* testsuite/25_algorithms/any_of/constexpr.cc: New.
	* testsuite/25_algorithms/binary_search/constexpr.cc: New.
	* testsuite/25_algorithms/copy/constexpr.cc: New.
	* testsuite/25_algorithms/copy_backward/constexpr.cc: New.
	* testsuite/25_algorithms/copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/copy_n/constexpr.cc: New.
	* testsuite/25_algorithms/count/constexpr.cc: New.
	* testsuite/25_algorithms/count_if/constexpr.cc: New.
	* testsuite/25_algorithms/equal/constexpr.cc: New.
	* testsuite/25_algorithms/equal_range/constexpr.cc: New.
	* testsuite/25_algorithms/fill/constexpr.cc: New.
	* testsuite/25_algorithms/fill_n/constexpr.cc: New.
	* testsuite/25_algorithms/find/constexpr.cc: New.
	* testsuite/25_algorithms/find_end/constexpr.cc: New.
	* testsuite/25_algorithms/find_first_of/constexpr.cc: New.
	* testsuite/25_algorithms/find_if/constexpr.cc: New.
	* testsuite/25_algorithms/find_if_not/constexpr.cc: New.
	* testsuite/25_algorithms/for_each/constexpr.cc: New.
	* testsuite/25_algorithms/generate/constexpr.cc: New.
	* testsuite/25_algorithms/generate_n/constexpr.cc: New.
	* testsuite/25_algorithms/is_heap/constexpr.cc: New.
	* testsuite/25_algorithms/is_heap_until/constexpr.cc: New.
	* testsuite/25_algorithms/is_partitioned/constexpr.cc: New.
	* testsuite/25_algorithms/is_permutation/constexpr.cc: New.
	* testsuite/25_algorithms/is_sorted/constexpr.cc: New.
	* testsuite/25_algorithms/is_sorted_until/constexpr.cc: New.
	* testsuite/25_algorithms/lexicographical_compare/constexpr.cc: New.
	* testsuite/25_algorithms/lower_bound/constexpr.cc: New.
	* testsuite/25_algorithms/merge/constexpr.cc: New.
	* testsuite/25_algorithms/mismatch/constexpr.cc: New.
	* testsuite/25_algorithms/none_of/constexpr.cc: New.
	* testsuite/25_algorithms/partition_copy/constexpr.cc: New.
	* testsuite/25_algorithms/partition_point/constexpr.cc: New.
	* testsuite/25_algorithms/remove/constexpr.cc: New.
	* testsuite/25_algorithms/remove_copy/constexpr.cc: New.
	* testsuite/25_algorithms/remove_copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/remove_if/constexpr.cc: New.
	* testsuite/25_algorithms/replace_copy/constexpr.cc: New.
	* testsuite/25_algorithms/replace_copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/replace_if/constexpr.cc: New.
	* testsuite/25_algorithms/reverse_copy/constexpr.cc: New.
	* testsuite/25_algorithms/rotate_copy/constexpr.cc: New.
	* testsuite/25_algorithms/search/constexpr.cc: New.
	* testsuite/25_algorithms/search_n/constexpr.cc: New.
	* testsuite/25_algorithms/set_difference/constexpr.cc: New.
	* testsuite/25_algorithms/set_intersection/constexpr.cc: New.
	* testsuite/25_algorithms/set_symmetric_difference/constexpr.cc: New.
	* testsuite/25_algorithms/set_union/constexpr.cc: New.
	* testsuite/25_algorithms/transform/constexpr.cc: New.
	* testsuite/25_algorithms/unique/constexpr.cc: New.
	* testsuite/25_algorithms/unique_copy/constexpr.cc: New.
	* testsuite/25_algorithms/upper_bound/constexpr.cc: New.

[-- Attachment #3: patch_constexpr_lib_2.bz2 --]
[-- Type: application/x-bzip, Size: 14941 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-06-26 23:13 Ed Smith-Rowland via libstdc++
  2019-06-27 15:41 ` Jonathan Wakely
@ 2019-07-02 12:11 ` Jonathan Wakely
  2019-07-06  3:11   ` Ed Smith-Rowland via libstdc++
  1 sibling, 1 reply; 21+ messages in thread
From: Jonathan Wakely @ 2019-07-02 12:11 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: libstdc++, gcc-patches

On 26/06/19 19:13 -0400, Ed Smith-Rowland via libstdc++ wrote:
>Here is the first of three patches for C++20 constexpr library.
>
>?????? Implement C++20 p0202 - Add constexpr Modifiers to Functions in 
><algorithm> and <utility> Headers.
>???? ??Implement C++20 p1023 - constexpr comparison operators for std::array.
>
>I believe I have answered peoples concerns with the last patch 
>attempts [https://gcc.gnu.org/ml/libstdc++/2019-03/msg00132.html].
>
>The patch is large because of test cases but really just boils down to 
>adding constexpr for c++2a.
>
>The patch passes testing for gnu++2a and pre-gnu++2a on x86_64-linux:
>
>$ make check -k -j4
>
>$ make check RUNTESTFLAGS=--target_board=unix/-std=gnu++2a -k -j4
>
>OK for trunk?

One more comment. In <bits/stl_algobase.h> this:

+#if __cplusplus > 201703L \
+    && defined(_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED)
+      if (__builtin_is_constant_evaluated())

can be simplified to just:

#ifdef __cpp_lib_is_constant_evaluated
      if (std::is_constant_evaluated())

The feature test macro is exactly the check we want here.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-06-27 23:07       ` Ed Smith-Rowland via libstdc++
@ 2019-06-27 23:31         ` Jonathan Wakely
  0 siblings, 0 replies; 21+ messages in thread
From: Jonathan Wakely @ 2019-06-27 23:31 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: Ville Voutilainen, libstdc++, gcc-patches

On 27/06/19 19:07 -0400, Ed Smith-Rowland wrote:
>On 6/27/19 1:06 PM, Ville Voutilainen wrote:
>>On Thu, 27 Jun 2019 at 19:55, Ed Smith-Rowland via libstdc++
>><libstdc++@gcc.gnu.org> wrote:
>>>>I don't think this will work in a constant expression:
>>>>
>>>>?? /// Assign @p __new_val to @p __obj and return its previous value.
>>>>?? template <typename _Tp, typename _Up = _Tp>
>>>>+?????? _GLIBCXX20_CONSTEXPR
>>>>?????? inline _Tp
>>>>?????? exchange(_Tp& __obj, _Up&& __new_val)
>>>>?????? { return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
>>>>
>>>>Because std::__exchange hasn't been marked constexpr. The test passes
>>>>because it doesn't call it in a context that requires constant
>>>>evaluation:
>>>>
>>>>??const auto x = std::exchange(e, pi);
>>>Derp.
>>>>I see the same problem in other tests too:
>>>>
>>>>+?? constexpr std::array<int, 12> car{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9,
>>>>11}};
>>>>+
>>>>+?? const auto out0x = std::adjacent_find(car.begin(), car.end());
>>>>+
>>>>+?? const auto out1x = std::adjacent_find(car.begin(), car.end(),
>>>>+?????????????????????????????????????? std::equal_to<int>())
>>>I will go through all the tests and make sure that some nontrivial
>>>calculation is done that contributes to a final bool return.?? And clean
>>>up the mess.?? I did this in chunk 2 but I guess I left a lot of chunk 1.
>>As was the case with the iterator patch, it's not a question of doing
>>a nontrivial calculation, but
>>a question of initializing a constexpr variable with the result. (Yeah
>>sure a non-type template
>>argument would also work but eurgh). Then, and only then, have we
>>proven that the code
>>works in a constexpr context. Initializing a const doesn't do that.
>>constinit would, but that's
>>C++20.
>>
>Ok, why isn't
>
>?? static_assert(test());
>
>a constexpr context?

It is, I missed that the array test does that at the bottom of the
file.


>The std::exchange test passed originally because, unlike all the other 
>algo tests I had neglected to call the test function in a constexpr 
>context.
>
>Note that constexpr_iter.c is this:
>
>----
>
>constexpr int
>test()
>{
>?? constexpr std::array<int, 3> a1{{1, 2, 3}};
>?? static_assert(1 == *a1.begin());
>?? auto n = a1[0] * a1[1]* a1[2];
>?? static_assert(1 == *a1.cbegin());
>
>?? std::array<int, 3> a2{{0, 0, 0}};
>?? auto a1i = a1.begin();
>?? auto a1e = a1.end();
>?? auto a2i = a2.begin();
>?? while (a1i != a1e)
>?????? *a2i++ = *a1i++;
>
>?? return n;
>}
>
>void
>run_test()
>{
>?? constexpr int n = test();
>}
>
>----
>
>Things inside the function can, and in many cases for this capability 
>must, be mutable.?? As long as the input and the final output is a 
>literal we should be good, no?
>
>Also when I assign returned iterators to constexpr I get:
>
>/home/ed/gcc_git/libstdc++-v3/testsuite/25_algorithms/find_if_not/constexpr.cc:36: 
>error: '(((std::array<int, 12>::const_pointer)(& ca0.std::array<int, 
>12>::_M_elems)) + 28)' is not a constant expression.

Yes, I tried adding that and got the same error, which is why I
thought the test had the same problem as the std::exchange one.

I'm not sure what causes that error, I'll take a look tomorrow.


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-06-27 17:06     ` Ville Voutilainen
@ 2019-06-27 23:07       ` Ed Smith-Rowland via libstdc++
  2019-06-27 23:31         ` Jonathan Wakely
  0 siblings, 1 reply; 21+ messages in thread
From: Ed Smith-Rowland via libstdc++ @ 2019-06-27 23:07 UTC (permalink / raw)
  To: Ville Voutilainen; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On 6/27/19 1:06 PM, Ville Voutilainen wrote:
> On Thu, 27 Jun 2019 at 19:55, Ed Smith-Rowland via libstdc++
> <libstdc++@gcc.gnu.org> wrote:
>>> I don't think this will work in a constant expression:
>>>
>>> ?? /// Assign @p __new_val to @p __obj and return its previous value.
>>> ?? template <typename _Tp, typename _Up = _Tp>
>>> +?????? _GLIBCXX20_CONSTEXPR
>>> ?????? inline _Tp
>>> ?????? exchange(_Tp& __obj, _Up&& __new_val)
>>> ?????? { return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
>>>
>>> Because std::__exchange hasn't been marked constexpr. The test passes
>>> because it doesn't call it in a context that requires constant
>>> evaluation:
>>>
>>> ??const auto x = std::exchange(e, pi);
>> Derp.
>>> I see the same problem in other tests too:
>>>
>>> +?? constexpr std::array<int, 12> car{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9,
>>> 11}};
>>> +
>>> +?? const auto out0x = std::adjacent_find(car.begin(), car.end());
>>> +
>>> +?? const auto out1x = std::adjacent_find(car.begin(), car.end(),
>>> +?????????????????????????????????????? std::equal_to<int>())
>> I will go through all the tests and make sure that some nontrivial
>> calculation is done that contributes to a final bool return.?? And clean
>> up the mess.?? I did this in chunk 2 but I guess I left a lot of chunk 1.
> As was the case with the iterator patch, it's not a question of doing
> a nontrivial calculation, but
> a question of initializing a constexpr variable with the result. (Yeah
> sure a non-type template
> argument would also work but eurgh). Then, and only then, have we
> proven that the code
> works in a constexpr context. Initializing a const doesn't do that.
> constinit would, but that's
> C++20.
>
Ok, why isn't

 ?? static_assert(test());

a constexpr context?

The std::exchange test passed originally because, unlike all the other 
algo tests I had neglected to call the test function in a constexpr context.

Note that constexpr_iter.c is this:

----

constexpr int
test()
{
 ?? constexpr std::array<int, 3> a1{{1, 2, 3}};
 ?? static_assert(1 == *a1.begin());
 ?? auto n = a1[0] * a1[1]* a1[2];
 ?? static_assert(1 == *a1.cbegin());

 ?? std::array<int, 3> a2{{0, 0, 0}};
 ?? auto a1i = a1.begin();
 ?? auto a1e = a1.end();
 ?? auto a2i = a2.begin();
 ?? while (a1i != a1e)
 ?????? *a2i++ = *a1i++;

 ?? return n;
}

void
run_test()
{
 ?? constexpr int n = test();
}

----

Things inside the function can, and in many cases for this capability 
must, be mutable.?? As long as the input and the final output is a 
literal we should be good, no?

Also when I assign returned iterators to constexpr I get:

/home/ed/gcc_git/libstdc++-v3/testsuite/25_algorithms/find_if_not/constexpr.cc:36: 
error: '(((std::array<int, 12>::const_pointer)(& ca0.std::array<int, 
12>::_M_elems)) + 28)' is not a constant expression.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-06-27 16:54   ` Ed Smith-Rowland via libstdc++
@ 2019-06-27 17:06     ` Ville Voutilainen
  2019-06-27 23:07       ` Ed Smith-Rowland via libstdc++
  0 siblings, 1 reply; 21+ messages in thread
From: Ville Voutilainen @ 2019-06-27 17:06 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: Jonathan Wakely, libstdc++, gcc-patches

On Thu, 27 Jun 2019 at 19:55, Ed Smith-Rowland via libstdc++
<libstdc++@gcc.gnu.org> wrote:
> > I don't think this will work in a constant expression:
> >
> > ?? /// Assign @p __new_val to @p __obj and return its previous value.
> > ?? template <typename _Tp, typename _Up = _Tp>
> > +?????? _GLIBCXX20_CONSTEXPR
> > ?????? inline _Tp
> > ?????? exchange(_Tp& __obj, _Up&& __new_val)
> > ?????? { return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
> >
> > Because std::__exchange hasn't been marked constexpr. The test passes
> > because it doesn't call it in a context that requires constant
> > evaluation:
> >
> > ??const auto x = std::exchange(e, pi);
> Derp.
> >
> > I see the same problem in other tests too:
> >
> > +?? constexpr std::array<int, 12> car{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9,
> > 11}};
> > +
> > +?? const auto out0x = std::adjacent_find(car.begin(), car.end());
> > +
> > +?? const auto out1x = std::adjacent_find(car.begin(), car.end(),
> > +?????????????????????????????????????? std::equal_to<int>())
>
> I will go through all the tests and make sure that some nontrivial
> calculation is done that contributes to a final bool return.?? And clean
> up the mess.?? I did this in chunk 2 but I guess I left a lot of chunk 1.

As was the case with the iterator patch, it's not a question of doing
a nontrivial calculation, but
a question of initializing a constexpr variable with the result. (Yeah
sure a non-type template
argument would also work but eurgh). Then, and only then, have we
proven that the code
works in a constexpr context. Initializing a const doesn't do that.
constinit would, but that's
C++20.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-06-27 15:41 ` Jonathan Wakely
@ 2019-06-27 16:54   ` Ed Smith-Rowland via libstdc++
  2019-06-27 17:06     ` Ville Voutilainen
  0 siblings, 1 reply; 21+ messages in thread
From: Ed Smith-Rowland via libstdc++ @ 2019-06-27 16:54 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches

On 6/27/19 11:41 AM, Jonathan Wakely wrote:
> On 26/06/19 19:13 -0400, Ed Smith-Rowland via libstdc++ wrote:
>> Here is the first of three patches for C++20 constexpr library.
>>
>> ?????? Implement C++20 p0202 - Add constexpr Modifiers to Functions 
>> in <algorithm> and <utility> Headers.
>> ???? ??Implement C++20 p1023 - constexpr comparison operators for 
>> std::array.
>>
>> I believe I have answered peoples concerns with the last patch 
>> attempts [https://gcc.gnu.org/ml/libstdc++/2019-03/msg00132.html].
>>
>> The patch is large because of test cases but really just boils down 
>> to adding constexpr for c++2a.
>
> I still have some concerns about the changes like:
>
> ?????? template<typename _Iterator, typename _Value>
> +?????????? _GLIBCXX20_CONSTEXPR
> ?????????? bool
> -?????????? operator()(_Iterator __it, _Value& __val) const
> +?????????? operator()(_Iterator __it, const _Value& __val) const
> ?????????? { return *__it < __val; }
>
Make a type where operator< changes the rhs.?? I was thinking you'd want 
a compare to operate on const things but I guess we have to be ready for 
anything.?? I was also thinking < is left associative for a class member 
but i guess a class could have a thing that mutates the rhs too.?? 
Nothing got hit in any of my testing.?? If this is a thing we probably 
should make a general test for things like this somewhere.?? Maybe 
someone wants to log references or something.

1. I'll experiment to see if I really need these (I *thought* I did, but...)

2. If I still do then I'll make overloads?

>
> I think that might change semantics for some types, and I haven't yet
> figured out if we care about those cases or not. I'll try to come up
> with some examples that change meaning.
>
> This could use _GLIBCXX14_CONSTEXPR:
>
> +?? /**
> +???? * A constexpr wrapper for __builtin_memmove.
> +???? * @param __num The number of elements of type _Tp (not bytes).
>
> I don't think we want a Doxygen comment for this, as it's not part of
> the public API. Just a normal comment is fine.
>
> +???? */
> +?? template<bool _IsMove, typename _Tp>
> +?????? _GLIBCXX20_CONSTEXPR
> +?????? inline void*
> +?????? __memmove(_Tp* __dst, const _Tp* __src, size_t __num)
> +?????? {
> +#if __cplusplus > 201703L \
> +?????? && defined(_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED)
> +?????????? if (__builtin_is_constant_evaluated())
> +?????? {
> +?????????? for(; __num > 0; --__num)
> +?????????????? {
> +?????????????????? if constexpr (_IsMove)
> +?????????????? *__dst = std::move(*__src);
> +?????????????????? else
> +?????????????? *__dst = *__src;
>
> Do we need this _IsMove condition here? We should only be using this
> function for trivially copyable types, in which case copy vs move
> shouldn't matter, should it?
>
> Oh ... is it because we also end up using this __memmove function for
> non-trivially copyable types, during constant evaluation? Hmm. Then
> it's more than just a wrapper for __builtin_memmove, right? It's
> "either memmove or constexpr range copy", or something.

Yup.?? I'm also bad at naming things.?? Furthermore, I expect the 
standards people to want to have our versions of memcpy, memcmp, memmove 
that we own and can make constexpr.?? These are such important concepts.

Also, part 2 brings in constexpr swap. Maybe this is the may to 
implement an actual memmove?

>
> I don't think this will work in a constant expression:
>
> ?? /// Assign @p __new_val to @p __obj and return its previous value.
> ?? template <typename _Tp, typename _Up = _Tp>
> +?????? _GLIBCXX20_CONSTEXPR
> ?????? inline _Tp
> ?????? exchange(_Tp& __obj, _Up&& __new_val)
> ?????? { return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
>
> Because std::__exchange hasn't been marked constexpr. The test passes
> because it doesn't call it in a context that requires constant
> evaluation:
>
> ??const auto x = std::exchange(e, pi);
Derp.
>
> I see the same problem in other tests too:
>
> +?? constexpr std::array<int, 12> car{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9, 
> 11}};
> +
> +?? const auto out0x = std::adjacent_find(car.begin(), car.end());
> +
> +?? const auto out1x = std::adjacent_find(car.begin(), car.end(),
> +?????????????????????????????????????? std::equal_to<int>())

I will go through all the tests and make sure that some nontrivial 
calculation is done that contributes to a final bool return.?? And clean 
up the mess.?? I did this in chunk 2 but I guess I left a lot of chunk 1.

Come to think of it, we could build *insane* concepts after this.?? For 
good or ill.

Ed

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/3] C++20 constexpr lib part 1/3
  2019-06-26 23:13 Ed Smith-Rowland via libstdc++
@ 2019-06-27 15:41 ` Jonathan Wakely
  2019-06-27 16:54   ` Ed Smith-Rowland via libstdc++
  2019-07-02 12:11 ` Jonathan Wakely
  1 sibling, 1 reply; 21+ messages in thread
From: Jonathan Wakely @ 2019-06-27 15:41 UTC (permalink / raw)
  To: Ed Smith-Rowland; +Cc: libstdc++, gcc-patches

On 26/06/19 19:13 -0400, Ed Smith-Rowland via libstdc++ wrote:
>Here is the first of three patches for C++20 constexpr library.
>
>?????? Implement C++20 p0202 - Add constexpr Modifiers to Functions in 
><algorithm> and <utility> Headers.
>???? ??Implement C++20 p1023 - constexpr comparison operators for std::array.
>
>I believe I have answered peoples concerns with the last patch 
>attempts [https://gcc.gnu.org/ml/libstdc++/2019-03/msg00132.html].
>
>The patch is large because of test cases but really just boils down to 
>adding constexpr for c++2a.

I still have some concerns about the changes like:

     template<typename _Iterator, typename _Value>
+      _GLIBCXX20_CONSTEXPR
       bool
-      operator()(_Iterator __it, _Value& __val) const
+      operator()(_Iterator __it, const _Value& __val) const
       { return *__it < __val; }


I think that might change semantics for some types, and I haven't yet
figured out if we care about those cases or not. I'll try to come up
with some examples that change meaning.

This could use _GLIBCXX14_CONSTEXPR:

+  /**
+   * A constexpr wrapper for __builtin_memmove.
+   * @param __num The number of elements of type _Tp (not bytes).

I don't think we want a Doxygen comment for this, as it's not part of
the public API. Just a normal comment is fine.

+   */
+  template<bool _IsMove, typename _Tp>
+    _GLIBCXX20_CONSTEXPR
+    inline void*
+    __memmove(_Tp* __dst, const _Tp* __src, size_t __num)
+    {
+#if __cplusplus > 201703L \
+    && defined(_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED)
+      if (__builtin_is_constant_evaluated())
+	{
+	  for(; __num > 0; --__num)
+	    {
+	      if constexpr (_IsMove)
+		*__dst = std::move(*__src);
+	      else
+		*__dst = *__src;

Do we need this _IsMove condition here? We should only be using this
function for trivially copyable types, in which case copy vs move
shouldn't matter, should it?

Oh ... is it because we also end up using this __memmove function for
non-trivially copyable types, during constant evaluation? Hmm. Then
it's more than just a wrapper for __builtin_memmove, right? It's
"either memmove or constexpr range copy", or something.

I don't think this will work in a constant expression:

   /// Assign @p __new_val to @p __obj and return its previous value.
   template <typename _Tp, typename _Up = _Tp>
+    _GLIBCXX20_CONSTEXPR
     inline _Tp
     exchange(_Tp& __obj, _Up&& __new_val)
     { return std::__exchange(__obj, std::forward<_Up>(__new_val)); }

Because std::__exchange hasn't been marked constexpr. The test passes
because it doesn't call it in a context that requires constant
evaluation:

  const auto x = std::exchange(e, pi);

I see the same problem in other tests too:

+  constexpr std::array<int, 12> car{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9, 11}};
+
+  const auto out0x = std::adjacent_find(car.begin(), car.end());
+
+  const auto out1x = std::adjacent_find(car.begin(), car.end(),
+					std::equal_to<int>());



^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/3] C++20 constexpr lib part 1/3
@ 2019-06-26 23:13 Ed Smith-Rowland via libstdc++
  2019-06-27 15:41 ` Jonathan Wakely
  2019-07-02 12:11 ` Jonathan Wakely
  0 siblings, 2 replies; 21+ messages in thread
From: Ed Smith-Rowland via libstdc++ @ 2019-06-26 23:13 UTC (permalink / raw)
  To: Jonathan Wakely, libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 679 bytes --]

Here is the first of three patches for C++20 constexpr library.

 ?????? Implement C++20 p0202 - Add constexpr Modifiers to Functions in 
<algorithm> and <utility> Headers.
 ???? ??Implement C++20 p1023 - constexpr comparison operators for std::array.

I believe I have answered peoples concerns with the last patch attempts 
[https://gcc.gnu.org/ml/libstdc++/2019-03/msg00132.html].

The patch is large because of test cases but really just boils down to 
adding constexpr for c++2a.

The patch passes testing for gnu++2a and pre-gnu++2a on x86_64-linux:

$ make check -k -j4

$ make check RUNTESTFLAGS=--target_board=unix/-std=gnu++2a -k -j4

OK for trunk?

Ed Smith-Rowland



[-- Attachment #2: CL_constexpr_lib --]
[-- Type: text/plain, Size: 7088 bytes --]

2019-06-26  Edward Smith-Rowland  <3dw4rd@verizon.net>

	Implement C++20 p0202 - Add Constexpr Modifiers to Functions
	in <algorithm> and <utility> Headers.
	Implement C++20 p1023 - constexpr comparison operators for std::array.
	* include/bits/algorithmfwd.h (all_of, any_of, binary_search, copy,
	copy_backward, copy_if, copy_n, equal_range, fill, find_end,
	find_if_not, includes, is_heap, is_heap_until, is_partitioned,
	is_permutation, is_sorted, is_sorted_until, iter_swap, lower_bound,
	none_of, partition_copy, partition_point, remove, remove_if,
	remove_copy, remove_copy_if, replace_copy, replace_copy_if,
	reverse_copy, rotate_copy, uunique, upper_bound, adjacent_find, count,
	count_if, equal, find, find_first_of, find_if, for_each, generate,
	generate_n, lexicographical_compare, merge, mismatch, replace,
	replace_if, search, search_n, set_difference, set_intersection,
	set_symmetric_difference, set_union, transform, unique_copy):
	Mark constexpr.
	* include/bits/cpp_type_traits.h (__miter_base): Mark constexpr.
	* include/bits/predefined_ops.h (_Iter_less_val::operator(),
	_Val_less_iter::operator(), _Iter_equal_to_iter::operator(),
	_Iter_equal_to_val::operator(), _Iter_equals_val::operator()):
	 Use const ref instead of ref arg;
	(_Iter_less_val, __iter_less_val, _Val_less_iter, __val_less_iter,
	__iter_equal_to_iter, __iter_equal_to_val, __iter_comp_val,
	_Iter_comp_val, _Val_comp_iter, __val_comp_iter, __iter_equals_val,
	_Iter_equals_iter, __iter_comp_iter, _Iter_pred, __pred_iter,
	_Iter_comp_to_val, __iter_comp_val, _Iter_comp_to_iter,
	__iter_comp_iter): Mark constexpr.
	* include/bits/stl_algo.h (__find_if, __find_if_not, __find_if_not_n,
	__search, __search_n_aux, __search_n, __find_end, find_end, all_of,
	none_of, any_of, find_if_not, is_partitioned, partition_point,
	__remove_copy_if, remove_copy, remove_copy_if, copy_if, __copy_n,
	copy_n, partition_copy, __remove_if, remove, remove_if, __adjacent_find,
	__unique, unique, __unique_copy, reverse_copy, rotate_copy,
	__unguarded_linear_insert, __insertion_sort, __unguarded_insertion_sort,
	__final_insertion_sort, lower_bound, __upper_bound, upper_bound,
	__equal_range, equal_range, binary_search, __includes, includes,
	__next_permutation, __prev_permutation, __replace_copy_if, replace_copy,
	replace_copy_if, __count_if, is_sorted, __is_sorted_until,
	is_sorted_until, __is_permutation, is_permutation, for_each, find,
	find_if, find_first_of, adjacent_find, count, count_if, search,
	search_n, transform, replace, replace_if, generate, generate_n,
	unique_copy, __merge, merge, __set_union, set_union, __set_intersection,
	set_intersection, __set_difference, set_difference,
	__set_symmetric_difference, set_symmetric_difference):  Mark constexpr.
	* include/bits/stl_algobase.h (__memmove, __memcmp): New maybe constexpr
	wrappers around __builtin_memmove and __builtin_memcmp
	respectively;
	(__niter_base, __niter_wrap, __copy_m, __copy_move_a, __copy_move_a2,
	copy, move, __copy_move_b, __copy_move_backward_a,
	__copy_move_backward_a2, copy_backward, move_backward, __fill_a, fill,
	__fill_n_a, fill_n, equal, __lc_rai::__newlast1, __lc_rai::__cnd2,
	__lexicographical_compare_impl, __lexicographical_compare,
	__lexicographical_compare<true>::__lc, __lexicographical_compare_aux,
	__lower_bound, lower_bound, equal, __equal4, lexicographical_compare,
	__mismatch, mismatch, __is_heap_until, __is_heap, is_heap_until,
	is_heap): Mark constexpr.
	* include/bits/stl_heap.h (__is_heap_until, __is_heap, is_heap_until,
	is_heap): Mark constexpr.
	* include/bits/stl_iterator.h (__niter_base, __miter_base): Mark constexpr.
	* include/std/array: Make comparison ops constexpr.
	* include/std/utility: Make exchange constexpr.
	* testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust.
	* testsuite/23_containers/array/tuple_interface/
	tuple_element_neg.cc: Adjust.
	* testsuite/20_util/exchange/constexpr.cc: New.
	* testsuite/23_containers/array/comparison_operators/constexpr.cc: New.
	* testsuite/25_algorithms/adjacent_find/constexpr.cc: New.
	* testsuite/25_algorithms/all_of/constexpr.cc: New.
	* testsuite/25_algorithms/any_of/constexpr.cc: New.
	* testsuite/25_algorithms/binary_search/constexpr.cc: New.
	* testsuite/25_algorithms/copy/constexpr.cc: New.
	* testsuite/25_algorithms/copy_backward/constexpr.cc: New.
	* testsuite/25_algorithms/copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/copy_n/constexpr.cc: New.
	* testsuite/25_algorithms/count/constexpr.cc: New.
	* testsuite/25_algorithms/count_if/constexpr.cc: New.
	* testsuite/25_algorithms/equal/constexpr.cc: New.
	* testsuite/25_algorithms/equal_range/constexpr.cc: New.
	* testsuite/25_algorithms/fill/constexpr.cc: New.
	* testsuite/25_algorithms/fill_n/constexpr.cc: New.
	* testsuite/25_algorithms/find/constexpr.cc: New.
	* testsuite/25_algorithms/find_end/constexpr.cc: New.
	* testsuite/25_algorithms/find_first_of/constexpr.cc: New.
	* testsuite/25_algorithms/find_if/constexpr.cc: New.
	* testsuite/25_algorithms/find_if_not/constexpr.cc: New.
	* testsuite/25_algorithms/for_each/constexpr.cc: New.
	* testsuite/25_algorithms/generate/constexpr.cc: New.
	* testsuite/25_algorithms/generate_n/constexpr.cc: New.
	* testsuite/25_algorithms/is_heap/constexpr.cc: New.
	* testsuite/25_algorithms/is_heap_until/constexpr.cc: New.
	* testsuite/25_algorithms/is_partitioned/constexpr.cc: New.
	* testsuite/25_algorithms/is_permutation/constexpr.cc: New.
	* testsuite/25_algorithms/is_sorted/constexpr.cc: New.
	* testsuite/25_algorithms/is_sorted_until/constexpr.cc: New.
	* testsuite/25_algorithms/lexicographical_compare/constexpr.cc: New.
	* testsuite/25_algorithms/lower_bound/constexpr.cc: New.
	* testsuite/25_algorithms/merge/constexpr.cc: New.
	* testsuite/25_algorithms/mismatch/constexpr.cc: New.
	* testsuite/25_algorithms/none_of/constexpr.cc: New.
	* testsuite/25_algorithms/partition_copy/constexpr.cc: New.
	* testsuite/25_algorithms/partition_point/constexpr.cc: New.
	* testsuite/25_algorithms/remove/constexpr.cc: New.
	* testsuite/25_algorithms/remove_copy/constexpr.cc: New.
	* testsuite/25_algorithms/remove_copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/remove_if/constexpr.cc: New.
	* testsuite/25_algorithms/replace_copy/constexpr.cc: New.
	* testsuite/25_algorithms/replace_copy_if/constexpr.cc: New.
	* testsuite/25_algorithms/replace_if/constexpr.cc: New.
	* testsuite/25_algorithms/reverse_copy/constexpr.cc: New.
	* testsuite/25_algorithms/rotate_copy/constexpr.cc: New.
	* testsuite/25_algorithms/search/constexpr.cc: New.
	* testsuite/25_algorithms/search_n/constexpr.cc: New.
	* testsuite/25_algorithms/set_difference/constexpr.cc: New.
	* testsuite/25_algorithms/set_intersection/constexpr.cc: New.
	* testsuite/25_algorithms/set_symmetric_difference/constexpr.cc: New.
	* testsuite/25_algorithms/set_union/constexpr.cc: New.
	* testsuite/25_algorithms/transform/constexpr.cc: New.
	* testsuite/25_algorithms/unique/constexpr.cc: New.
	* testsuite/25_algorithms/unique_copy/constexpr.cc: New.
	* testsuite/25_algorithms/upper_bound/constexpr.cc: New.

[-- Attachment #3: patch_constexpr_lib.bz2 --]
[-- Type: application/x-bzip, Size: 13576 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2019-08-07 15:58 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-06 15:30 [PATCH 1/3] C++20 constexpr lib part 1/3 Steve Ellcey
2019-08-06 20:04 ` Jonathan Wakely
2019-08-06 20:30   ` [EXT] " Steve Ellcey
2019-08-06 20:47     ` Marek Polacek
2019-08-06 21:12       ` Steve Ellcey
2019-08-07 15:58 ` Ed Smith-Rowland via libstdc++
  -- strict thread matches above, loose matches on Subject: below --
2019-06-26 23:13 Ed Smith-Rowland via libstdc++
2019-06-27 15:41 ` Jonathan Wakely
2019-06-27 16:54   ` Ed Smith-Rowland via libstdc++
2019-06-27 17:06     ` Ville Voutilainen
2019-06-27 23:07       ` Ed Smith-Rowland via libstdc++
2019-06-27 23:31         ` Jonathan Wakely
2019-07-02 12:11 ` Jonathan Wakely
2019-07-06  3:11   ` Ed Smith-Rowland via libstdc++
2019-07-06  7:55     ` Ville Voutilainen
2019-07-11 16:40       ` Ed Smith-Rowland via libstdc++
2019-07-31 14:50       ` Ed Smith-Rowland via libstdc++
2019-08-01 10:56         ` Jonathan Wakely
2019-08-01 15:47           ` Ed Smith-Rowland via libstdc++
2019-08-01 19:45             ` Jonathan Wakely
2019-08-02  1:04               ` Ed Smith-Rowland via libstdc++

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).