aboutsummaryrefslogtreecommitdiffstats
path: root/nihil.generator/elements_of.ccm
blob: 0e34eb9465292aa8d87d7a4ae2657efd15d88e7b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
///////////////////////////////////////////////////////////////////////////////
// Reference implementation of std::generator proposal P2168.
//
// See https://wg21.link/P2168 for details.
//
///////////////////////////////////////////////////////////////////////////////
// Copyright Lewis Baker, Corentin Jabot
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0.
// (See accompanying file LICENSE or http://www.boost.org/LICENSE_1_0.txt)
///////////////////////////////////////////////////////////////////////////////

module;

#include <concepts>

export module nihil.generator:elements_of;

import :util;

namespace nihil {

export template <typename Range, typename Allocator = use_allocator_arg>
struct elements_of {
	explicit constexpr elements_of(Range &&range) noexcept
	requires std::is_default_constructible_v<Allocator>
		: m_range(static_cast<Range &&>(range))
	{
	}

	constexpr elements_of(Range &&range, Allocator &&alloc) noexcept
		: m_range(static_cast<Range &&>(range))
		, m_alloc(static_cast<Allocator &&>(alloc))
	{}

	constexpr elements_of(elements_of &&) noexcept = default;

	constexpr elements_of(const elements_of &) = delete;

	constexpr auto operator=(this elements_of &, const elements_of &)
		-> elements_of & = delete;
	constexpr auto operator=(this elements_of &, elements_of &&) noexcept
		-> elements_of & = delete;

	[[nodiscard]] constexpr auto
	get(this elements_of const &self) noexcept -> Range &&
	{
		return static_cast<Range &&>(self.m_range);
	}

	[[nodiscard]] constexpr auto
	get_allocator(this elements_of const &self) noexcept -> Allocator
	{
		return self.m_alloc;
	}

private:
	[[no_unique_address]] Allocator m_alloc;
	Range &&m_range;
};

export template <typename Range>
elements_of(Range &&) -> elements_of<Range>;

export template <typename Range, typename Allocator>
elements_of(Range &&, Allocator &&) -> elements_of<Range, Allocator>;

} // namespace nihil