14 template<
typename TChainInput>
15 class [[nodiscard(CXXITER_CHAINER_NODISCARD_WARNING)]] TakeN :
public IterApi<TakeN<TChainInput>> {
16 friend struct trait::Iterator<TakeN<TChainInput>>;
22 constexpr TakeN(TChainInput&& input,
size_t n) : input(std::move(input)), n(n), remaining(n) {}
27 template<
typename TChainInput>
28 struct trait::Iterator<op::TakeN<TChainInput>> {
29 using ChainInputIterator = trait::Iterator<TChainInput>;
30 using InputItem =
typename TChainInput::Item;
32 using Self = op::TakeN<TChainInput>;
33 using Item = InputItem;
35 static constexpr inline IterValue<Item> next(Self& self) {
36 if(self.remaining == 0) [[unlikely]] {
return {}; }
37 auto item = ChainInputIterator::next(self.input);
38 if(!item.has_value()) [[unlikely]] {
return {}; }
42 static constexpr inline SizeHint sizeHint(
const Self& self) {
43 SizeHint input = ChainInputIterator::sizeHint(self.input);
45 std::min(input.lowerBound, self.n),
46 SizeHint::upperBoundMin(input.upperBound, self.n)
49 static constexpr inline size_t advanceBy(Self& self,
size_t n) {
50 size_t skipN = ChainInputIterator::advanceby(self.input, n);
51 if(self.n < skipN) { self.n = 0; }
else { self.n -= skipN; }
56 template<CXXIterExactSizeIterator TChainInput>
57 struct trait::ExactSizeIterator<op::TakeN<TChainInput>> {
58 static constexpr inline size_t size(
const op::TakeN<TChainInput>& self) {
59 return trait::Iterator<op::TakeN<TChainInput>>::sizeHint(self).lowerBound;