Skip to content

Commit

Permalink
Implement ranges::fill and ranges::fill_n
Browse files Browse the repository at this point in the history
  • Loading branch information
CaseyCarter committed Jun 26, 2020
1 parent 4deaf6c commit ad0055a
Show file tree
Hide file tree
Showing 7 changed files with 420 additions and 133 deletions.
79 changes: 79 additions & 0 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -2841,6 +2841,85 @@ _FwdIt2 replace_copy_if(_ExPo&&, _FwdIt1 _First, _FwdIt1 _Last, _FwdIt2 _Dest, _
}
#endif // _HAS_CXX17

#ifdef __cpp_lib_concepts
namespace ranges {
// VARIABLE ranges::fill
class _Fill_fn : private _Not_quite_object {
public:
using _Not_quite_object::_Not_quite_object;

template <class _Ty, output_iterator<const _Ty&> _It, sentinel_for<_It> _Se>
constexpr _It operator()(_It _First, _Se _Last, const _Ty& _Value) const {
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_STD move(_First));
const auto _ULast = _Get_unwrapped(_STD move(_Last));
if constexpr (_Fill_memset_is_safe<decltype(_UFirst), _Ty>) {
#ifdef __cpp_lib_is_constant_evaluated
if (!_STD is_constant_evaluated())
#endif // __cpp_lib_is_constant_evaluated
{
const int distance = static_cast<size_t>(_ULast - _UFirst);
_CSTD memset(_UFirst, static_cast<unsigned char>(_Value), distance);
_UFirst += distance;
_Seek_wrapped(_First, _UFirst);
return _First;
}
}

for (; _UFirst != _ULast; ++_UFirst) {
*_UFirst = _Value;
}

_Seek_wrapped(_First, _STD move(_UFirst));
return _First;
}

template <class _Ty, output_range<const _Ty&> _Rng>
constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, const _Ty& _Value) const {
auto _First = _RANGES begin(_Range);
_Seek_wrapped(_First, (*this)(_Get_unwrapped(_STD move(_First)), _Uend(_Range), _Value));
return _First;
}
};

inline constexpr _Fill_fn fill{_Not_quite_object::_Construct_tag{}};

// VARIABLE ranges::fill_n
class _Fill_n_fn : private _Not_quite_object {
public:
using _Not_quite_object::_Not_quite_object;

template <class _Ty, output_iterator<const _Ty&> _It>
constexpr _It operator()(_It _First, iter_difference_t<_It> _Count, const _Ty& _Value) const {
if (_Count >= 0) {
auto _UFirst = _Get_unwrapped_n(_STD move(_First), _Count);
if constexpr (_Fill_memset_is_safe<decltype(_UFirst), _Ty>) {
#ifdef __cpp_lib_is_constant_evaluated
if (!_STD is_constant_evaluated())
#endif // __cpp_lib_is_constant_evaluated
{
_CSTD memset(_UFirst, static_cast<unsigned char>(_Value), static_cast<size_t>(_Count));
_UFirst += _Count;
_Seek_wrapped(_First, _UFirst);
return _First;
}
}

for (; _Count > 0; ++_UFirst, (void) --_Count) {
*_UFirst = _Value;
}

_Seek_wrapped(_First, _STD move(_UFirst));
}

return _First;
}
};

inline constexpr _Fill_n_fn fill_n{_Not_quite_object::_Construct_tag{}};
} // namespace ranges
#endif // __cpp_lib_concepts

// FUNCTION TEMPLATE generate
template <class _FwdIt, class _Fn>
_CONSTEXPR20 void generate(_FwdIt _First, _FwdIt _Last, _Fn _Func) { // replace [_First, _Last) with _Func()
Expand Down
Loading

0 comments on commit ad0055a

Please sign in to comment.