Skip to content

Commit

Permalink
Making them constexpr:
Browse files Browse the repository at this point in the history
* accumulate
* inner_product
* partial_sum
* exclusive_scan
* inclusive_scan
* transform_exclusive_scan
* transform_inclusive_scan
* adjacent_difference
* iota
  • Loading branch information
Neargye committed Dec 19, 2019
1 parent 098333c commit 4803767
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 38 deletions.
70 changes: 36 additions & 34 deletions stl/inc/numeric
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ _STL_DISABLE_CLANG_WARNINGS
_STD_BEGIN
// FUNCTION TEMPLATE accumulate
template <class _InIt, class _Ty, class _Fn>
_NODISCARD _Ty accumulate(const _InIt _First, const _InIt _Last, _Ty _Val, _Fn _Reduce_op) {
_NODISCARD _CONSTEXPR20 _Ty accumulate(const _InIt _First, const _InIt _Last, _Ty _Val, _Fn _Reduce_op) {
// return noncommutative and nonassociative reduction of _Val and all in [_First, _Last), using _Reduce_op
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
Expand All @@ -39,7 +39,7 @@ _NODISCARD _Ty accumulate(const _InIt _First, const _InIt _Last, _Ty _Val, _Fn _
}

template <class _InIt, class _Ty>
_NODISCARD _Ty accumulate(const _InIt _First, const _InIt _Last, _Ty _Val) {
_NODISCARD _CONSTEXPR20 _Ty accumulate(const _InIt _First, const _InIt _Last, _Ty _Val) {
// return noncommutative and nonassociative reduction of _Val and all in [_First, _Last)
return _STD accumulate(_First, _Last, _Val, plus<>());
}
Expand Down Expand Up @@ -122,7 +122,7 @@ _NODISCARD _Iter_value_t<_FwdIt> reduce(

// FUNCTION TEMPLATE inner_product
template <class _InIt1, class _InIt2, class _Ty, class _BinOp1, class _BinOp2>
_NODISCARD _Ty inner_product(
_NODISCARD _CONSTEXPR20 _Ty inner_product(
_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _Ty _Val, _BinOp1 _Reduce_op, _BinOp2 _Transform_op) {
// return noncommutative and nonassociative transform-reduction of sequences, using
// _Reduce_op and _Transform_op
Expand All @@ -143,8 +143,8 @@ _NODISCARD _Ty inner_product(

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt1, class _RightTy, size_t _RightSize, class _Ty, class _BinOp1, class _BinOp2>
_NODISCARD _Ty inner_product(const _InIt1 _First1, const _InIt1 _Last1, _RightTy (&_First2)[_RightSize], _Ty _Val,
_BinOp1 _Reduce_op, _BinOp2 _Transform_op) {
_NODISCARD _CONSTEXPR20 _Ty inner_product(const _InIt1 _First1, const _InIt1 _Last1, _RightTy (&_First2)[_RightSize],
_Ty _Val, _BinOp1 _Reduce_op, _BinOp2 _Transform_op) {
// return noncommutative and nonassociative transform-reduction of sequences, using
// _Reduce_op and _Transform_op
return _STD inner_product(_First1, _Last1, _Array_iterator<_RightTy, _RightSize>(_First2), _STD move(_Val),
Expand All @@ -153,14 +153,15 @@ _NODISCARD _Ty inner_product(const _InIt1 _First1, const _InIt1 _Last1, _RightTy
#endif // _ITERATOR_DEBUG_ARRAY_OVERLOADS

template <class _InIt1, class _InIt2, class _Ty>
_NODISCARD _Ty inner_product(const _InIt1 _First1, const _InIt1 _Last1, const _InIt2 _First2, _Ty _Val) {
_NODISCARD _CONSTEXPR20 _Ty inner_product(const _InIt1 _First1, const _InIt1 _Last1, const _InIt2 _First2, _Ty _Val) {
// return noncommutative and nonassociative transform-reduction of sequences
return _STD inner_product(_First1, _Last1, _First2, _STD move(_Val), plus<>(), multiplies<>());
}

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt1, class _RightTy, size_t _RightSize, class _Ty>
_NODISCARD _Ty inner_product(const _InIt1 _First1, const _InIt1 _Last1, _RightTy (&_First2)[_RightSize], _Ty _Val) {
_NODISCARD _CONSTEXPR20 _Ty inner_product(
const _InIt1 _First1, const _InIt1 _Last1, _RightTy (&_First2)[_RightSize], _Ty _Val) {
// return noncommutative and nonassociative transform-reduction of sequences
return _STD inner_product(_First1, _Last1, _First2, _STD move(_Val), plus<>(), multiplies<>());
}
Expand Down Expand Up @@ -300,7 +301,7 @@ _NODISCARD _Ty transform_reduce(_ExPo&& _Exec, const _FwdIt _First1, const _FwdI

// FUNCTION TEMPLATE partial_sum
template <class _InIt, class _OutIt, class _BinOp>
_OutIt partial_sum(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Reduce_op) {
_CONSTEXPR20 _OutIt partial_sum(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Reduce_op) {
// compute partial noncommutative and nonassociative reductions into _Dest, using _Reduce_op
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
Expand Down Expand Up @@ -330,22 +331,22 @@ _OutIt partial_sum(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _BinOp>
_DestTy* partial_sum(_InIt _First, _InIt _Last, _DestTy (&_Dest)[_DestSize], _BinOp _Reduce_op) {
_CONSTEXPR20 _DestTy* partial_sum(_InIt _First, _InIt _Last, _DestTy (&_Dest)[_DestSize], _BinOp _Reduce_op) {
// compute partial noncommutative and nonassociative reductions into _Dest, using _Reduce_op
return _STD partial_sum(_First, _Last, _Array_iterator<_DestTy, _DestSize>(_Dest), _Pass_fn(_Reduce_op))
._Unwrapped();
}
#endif // _ITERATOR_DEBUG_ARRAY_OVERLOADS

template <class _InIt, class _OutIt>
_OutIt partial_sum(_InIt _First, _InIt _Last, _OutIt _Dest) {
_CONSTEXPR20 _OutIt partial_sum(_InIt _First, _InIt _Last, _OutIt _Dest) {
// compute partial noncommutative and nonassociative reductions into _Dest
return _STD partial_sum(_First, _Last, _Dest, plus<>());
}

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize>
_DestTy* partial_sum(_InIt _First, _InIt _Last, _DestTy (&_Dest)[_DestSize]) {
_CONSTEXPR20 _DestTy* partial_sum(_InIt _First, _InIt _Last, _DestTy (&_Dest)[_DestSize]) {
// compute partial noncommutative and nonassociative reductions into _Dest
return _STD partial_sum(_First, _Last, _Dest, plus<>());
}
Expand All @@ -354,7 +355,7 @@ _DestTy* partial_sum(_InIt _First, _InIt _Last, _DestTy (&_Dest)[_DestSize]) {
#if _HAS_CXX17
// FUNCTION TEMPLATE exclusive_scan
template <class _InIt, class _OutIt, class _Ty, class _BinOp>
_OutIt exclusive_scan(const _InIt _First, const _InIt _Last, _OutIt _Dest, _Ty _Val, _BinOp _Reduce_op) {
_CONSTEXPR20 _OutIt exclusive_scan(const _InIt _First, const _InIt _Last, _OutIt _Dest, _Ty _Val, _BinOp _Reduce_op) {
// set each value in [_Dest, _Dest + (_Last - _First)) to the associative reduction of predecessors and _Val
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
Expand All @@ -380,7 +381,7 @@ _OutIt exclusive_scan(const _InIt _First, const _InIt _Last, _OutIt _Dest, _Ty _

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _Ty, class _BinOp>
_DestTy* exclusive_scan(
_CONSTEXPR20 _DestTy* exclusive_scan(
const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _Ty _Val, _BinOp _Reduce_op) {
// set each value in [_Dest, _Dest + (_Last - _First)) to the associative reduction of predecessors and _Val
return _STD exclusive_scan(
Expand All @@ -390,14 +391,14 @@ _DestTy* exclusive_scan(
#endif // _ITERATOR_DEBUG_ARRAY_OVERLOADS

template <class _InIt, class _OutIt, class _Ty>
_OutIt exclusive_scan(const _InIt _First, const _InIt _Last, const _OutIt _Dest, _Ty _Val) {
_CONSTEXPR20 _OutIt exclusive_scan(const _InIt _First, const _InIt _Last, const _OutIt _Dest, _Ty _Val) {
// set each value in [_Dest, _Dest + (_Last - _First)) to the associative reduction of predecessors and _Val
return _STD exclusive_scan(_First, _Last, _Dest, _STD move(_Val), plus<>{});
}

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _Ty>
_DestTy* exclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _Ty _Val) {
_CONSTEXPR20 _DestTy* exclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _Ty _Val) {
// set each value in [_Dest, _Dest + (_Last - _First)) to the associative reduction of predecessors and _Val
return _STD exclusive_scan(_First, _Last, _Dest, _STD move(_Val), plus<>{});
}
Expand Down Expand Up @@ -438,7 +439,7 @@ _DestTy* exclusive_scan(_ExPo&& _Exec, const _FwdIt1 _First, const _FwdIt1 _Last

// FUNCTION TEMPLATE inclusive_scan
template <class _InIt, class _OutIt, class _Ty, class _BinOp>
_OutIt inclusive_scan(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Reduce_op, _Ty _Val) {
_CONSTEXPR20 _OutIt inclusive_scan(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Reduce_op, _Ty _Val) {
// compute partial noncommutative and associative reductions including _Val into _Dest, using _Reduce_op
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
Expand All @@ -456,7 +457,7 @@ _OutIt inclusive_scan(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinO

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _Ty, class _BinOp>
_DestTy* inclusive_scan(
_CONSTEXPR20 _DestTy* inclusive_scan(
const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _BinOp _Reduce_op, _Ty _Val) {
// compute partial noncommutative and associative reductions including _Val into _Dest, using _Reduce_op
return _STD inclusive_scan(
Expand All @@ -466,7 +467,7 @@ _DestTy* inclusive_scan(
#endif // _ITERATOR_DEBUG_ARRAY_OVERLOADS

template <class _InIt, class _OutIt, class _BinOp>
_OutIt inclusive_scan(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Reduce_op) {
_CONSTEXPR20 _OutIt inclusive_scan(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Reduce_op) {
// compute partial noncommutative and associative reductions into _Dest, using _Reduce_op
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
Expand All @@ -492,22 +493,22 @@ _OutIt inclusive_scan(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinO

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _BinOp>
_DestTy* inclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _BinOp _Reduce_op) {
_CONSTEXPR20 _DestTy* inclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _BinOp _Reduce_op) {
// compute partial noncommutative and associative reductions into _Dest, using _Reduce_op
return _STD inclusive_scan(_First, _Last, _Array_iterator<_DestTy, _DestSize>(_Dest), _Pass_fn(_Reduce_op))
._Unwrapped();
}
#endif // _ITERATOR_DEBUG_ARRAY_OVERLOADS

template <class _InIt, class _OutIt>
_OutIt inclusive_scan(const _InIt _First, const _InIt _Last, const _OutIt _Dest) {
_CONSTEXPR20 _OutIt inclusive_scan(const _InIt _First, const _InIt _Last, const _OutIt _Dest) {
// compute partial noncommutative and associative reductions into _Dest
return _STD inclusive_scan(_First, _Last, _Dest, plus<>{});
}

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize>
_DestTy* inclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize]) {
_CONSTEXPR20 _DestTy* inclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize]) {
// compute partial noncommutative and associative reductions into _Dest
return _STD inclusive_scan(_First, _Last, _Dest, plus<>{});
}
Expand Down Expand Up @@ -566,7 +567,7 @@ _DestTy* inclusive_scan(

// FUNCTION TEMPLATE transform_exclusive_scan
template <class _InIt, class _OutIt, class _Ty, class _BinOp, class _UnaryOp>
_OutIt transform_exclusive_scan(
_CONSTEXPR20 _OutIt transform_exclusive_scan(
const _InIt _First, const _InIt _Last, _OutIt _Dest, _Ty _Val, _BinOp _Reduce_op, _UnaryOp _Transform_op) {
// set each value in [_Dest, _Dest + (_Last - _First)) to the associative reduction of transformed predecessors
_Adl_verify_range(_First, _Last);
Expand All @@ -593,8 +594,8 @@ _OutIt transform_exclusive_scan(

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _Ty, class _BinOp, class _UnaryOp>
_DestTy* transform_exclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _Ty _Val,
_BinOp _Reduce_op, _UnaryOp _Transform_op) {
_CONSTEXPR20 _DestTy* transform_exclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize],
_Ty _Val, _BinOp _Reduce_op, _UnaryOp _Transform_op) {
// set each value in [_Dest, _Dest + (_Last - _First)) to the associative reduction of transformed predecessors
return _STD transform_exclusive_scan(_First, _Last, _Array_iterator<_DestTy, _DestSize>(_Dest), _STD move(_Val),
_Pass_fn(_Reduce_op), _Pass_fn(_Transform_op))
Expand All @@ -621,7 +622,7 @@ _DestTy* transform_exclusive_scan(_ExPo&& _Exec, const _FwdIt1 _First, const _Fw

// FUNCTION TEMPLATE transform_inclusive_scan
template <class _InIt, class _OutIt, class _Ty, class _BinOp, class _UnaryOp>
_OutIt transform_inclusive_scan(
_CONSTEXPR20 _OutIt transform_inclusive_scan(
const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Reduce_op, _UnaryOp _Transform_op, _Ty _Val) {
// compute partial noncommutative and associative transformed reductions including _Val into _Dest
_Adl_verify_range(_First, _Last);
Expand All @@ -640,8 +641,8 @@ _OutIt transform_inclusive_scan(

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _Ty, class _BinOp, class _UnaryOp>
_DestTy* transform_inclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _BinOp _Reduce_op,
_UnaryOp _Transform_op, _Ty _Val) {
_CONSTEXPR20 _DestTy* transform_inclusive_scan(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize],
_BinOp _Reduce_op, _UnaryOp _Transform_op, _Ty _Val) {
// compute partial noncommutative and associative transformed reductions including _Val into _Dest
return _STD transform_inclusive_scan(_First, _Last, _Array_iterator<_DestTy, _DestSize>(_Dest),
_Pass_fn(_Reduce_op), _Pass_fn(_Transform_op), _STD move(_Val))
Expand All @@ -650,7 +651,7 @@ _DestTy* transform_inclusive_scan(const _InIt _First, const _InIt _Last, _DestTy
#endif // _ITERATOR_DEBUG_ARRAY_OVERLOADS

template <class _InIt, class _OutIt, class _BinOp, class _UnaryOp>
_OutIt transform_inclusive_scan(
_CONSTEXPR20 _OutIt transform_inclusive_scan(
const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Reduce_op, _UnaryOp _Transform_op) {
// compute partial noncommutative and associative transformed reductions into _Dest
_Adl_verify_range(_First, _Last);
Expand All @@ -677,7 +678,7 @@ _OutIt transform_inclusive_scan(

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _BinOp, class _UnaryOp>
_DestTy* transform_inclusive_scan(
_CONSTEXPR20 _DestTy* transform_inclusive_scan(
const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _BinOp _Reduce_op, _UnaryOp _Transform_op) {
// compute partial noncommutative and associative transformed reductions into _Dest
return _STD transform_inclusive_scan(
Expand Down Expand Up @@ -723,7 +724,7 @@ _DestTy* transform_inclusive_scan(_ExPo&& _Exec, const _FwdIt1 _First, const _Fw

// FUNCTION TEMPLATE adjacent_difference
template <class _InIt, class _OutIt, class _BinOp>
_OutIt adjacent_difference(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Func) {
_CONSTEXPR20 _OutIt adjacent_difference(const _InIt _First, const _InIt _Last, _OutIt _Dest, _BinOp _Func) {
// compute adjacent differences into _Dest
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
Expand Down Expand Up @@ -751,22 +752,23 @@ _OutIt adjacent_difference(const _InIt _First, const _InIt _Last, _OutIt _Dest,

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize, class _BinOp>
_DestTy* adjacent_difference(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _BinOp _Func) {
_CONSTEXPR20 _DestTy* adjacent_difference(
const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize], _BinOp _Func) {
// compute adjacent differences into _Dest
return _STD adjacent_difference(_First, _Last, _Array_iterator<_DestTy, _DestSize>(_Dest), _Pass_fn(_Func))
._Unwrapped();
}
#endif // _ITERATOR_DEBUG_ARRAY_OVERLOADS

template <class _InIt, class _OutIt>
_OutIt adjacent_difference(const _InIt _First, const _InIt _Last, const _OutIt _Dest) {
_CONSTEXPR20 _OutIt adjacent_difference(const _InIt _First, const _InIt _Last, const _OutIt _Dest) {
// compute adjacent differences into _Dest
return _STD adjacent_difference(_First, _Last, _Dest, minus<>());
}

#if _ITERATOR_DEBUG_ARRAY_OVERLOADS
template <class _InIt, class _DestTy, size_t _DestSize>
_DestTy* adjacent_difference(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize]) {
_CONSTEXPR20 _DestTy* adjacent_difference(const _InIt _First, const _InIt _Last, _DestTy (&_Dest)[_DestSize]) {
// compute adjacent differences into _Dest
return _STD adjacent_difference(_First, _Last, _Dest, minus<>());
}
Expand Down Expand Up @@ -808,7 +810,7 @@ _DestTy* adjacent_difference(

// FUNCTION TEMPLATE iota
template <class _FwdIt, class _Ty>
void iota(_FwdIt _First, _FwdIt _Last, _Ty _Val) {
_CONSTEXPR20 void iota(_FwdIt _First, _FwdIt _Last, _Ty _Val) {
// compute increasing sequence into [_First, _Last)
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
Expand Down
8 changes: 4 additions & 4 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -1330,7 +1330,7 @@ using _Enable_if_execution_policy_t = typename remove_reference_t<_ExPo>::_Stand
// FUNCTION TEMPLATE _Idl_distance
#if _HAS_IF_CONSTEXPR
template <class _Checked, class _Iter>
auto _Idl_distance(const _Iter& _First, const _Iter& _Last) {
constexpr auto _Idl_distance(const _Iter& _First, const _Iter& _Last) {
// tries to get the distance between _First and _Last if they are random-access iterators
if constexpr (_Is_random_iter_v<_Iter>) {
return static_cast<_Iter_diff_t<_Checked>>(_Last - _First);
Expand All @@ -1342,19 +1342,19 @@ auto _Idl_distance(const _Iter& _First, const _Iter& _Last) {
}
#else // ^^^ _HAS_IF_CONSTEXPR / !_HAS_IF_CONSTEXPR vvv
template <class _Checked, class _Iter>
_Distance_unknown _Idl_distance1(const _Iter&, const _Iter&, input_iterator_tag) {
constexpr _Distance_unknown _Idl_distance1(const _Iter&, const _Iter&, input_iterator_tag) {
// _Idl_distance for non-random-access iterators
return {};
}

template <class _Checked, class _Iter>
_Iter_diff_t<_Checked> _Idl_distance1(const _Iter& _First, const _Iter& _Last, random_access_iterator_tag) {
constexpr _Iter_diff_t<_Checked> _Idl_distance1(const _Iter& _First, const _Iter& _Last, random_access_iterator_tag) {
// _Idl_distance for random-access iterators
return static_cast<_Iter_diff_t<_Checked>>(_Last - _First);
}

template <class _Checked, class _Iter>
auto _Idl_distance(const _Iter& _First, const _Iter& _Last) {
constexpr auto _Idl_distance(const _Iter& _First, const _Iter& _Last) {
// tries to get the distance between _First and _Last if they are random-access iterators
return _Idl_distance1<_Checked>(_First, _Last, _Iter_cat_t<_Iter>());
}
Expand Down

0 comments on commit 4803767

Please sign in to comment.