diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd3b7fe..ec9c62e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,18 +38,31 @@ jobs: - name: Build and Test run: bash tools/earthly.sh +build-gcc-10.3 + # XXX: BROKEN due to compiler bugs. Investigate at a later date. build-clang16: - name: Build for Clang 16 + name: Build for Clang 16 [Compiler bugs] runs-on: ubuntu-latest + if: ${{false}} # Skipped steps: - name: Checkout uses: actions/checkout@v4 - name: Build and Test run: bash tools/earthly.sh +build-clang-16 + build-clang17: + name: Build for Clang 17 [Compiler bugs] + runs-on: ubuntu-latest + if: ${{false}} # Skipped + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build and Test + run: bash tools/earthly.sh +build-clang-17 + build-vs2019: - name: Build for VS 2019 + name: Build for VS 2019 [Compiler bugs] runs-on: windows-2019 + if: ${{false}} # Skipped steps: - name: Checkout uses: actions/checkout@v4 diff --git a/Earthfile b/Earthfile index 585204c..4ffaaf7 100644 --- a/Earthfile +++ b/Earthfile @@ -89,6 +89,9 @@ build-gcc: build-gcc-10.3: DO +ALPINE_BUILD --version=3.15 --prep=ALPINE_PREP_GCC --cxx_flags="-fcoroutines" --runtime_debug=false +build-clang-17: + DO +ALPINE_BUILD --version=3.19 --prep=ALPINE_PREP_CLANG + build-clang-16: DO +ALPINE_BUILD --version=3.18 --prep=ALPINE_PREP_CLANG diff --git a/render.py b/render.py new file mode 100644 index 0000000..f2a1b71 --- /dev/null +++ b/render.py @@ -0,0 +1,47 @@ +# /// script +# requires-python = ">=3.8" +# dependencies = [] +# "jinja2", +# ] +# /// +import sys +from typing import Any, Sequence +import jinja2 +import argparse + + +def format_each(iterable: Any, s: str) -> Any: + return (s.format(x) for x in iterable) + + +_GENERATED_FILE_WARNING = """// d8888b. .d88b. d8b db .d88b. d888888b d88888b d8888b. d888888b d888888b +// 88 `8D .8P Y8. 888o 88 .8P Y8. `~~88~~' 88' 88 `8D `88' `~~88~~' +// 88 88 88 88 88V8o 88 88 88 88 88ooooo 88 88 88 88 +// 88 88 88 88 88 V8o88 88 88 88 88~~~~~ 88 88 88 88 +// 88 .8D `8b d8' 88 V888 `8b d8' 88 88. 88 .8D .88. 88 +// Y8888D' `Y88P' VP V8P `Y88P' YP Y88888P Y8888D' Y888888P YP""" + + +def gen_warning(filename: str) -> str: + return f"{_GENERATED_FILE_WARNING}\n\n// This file was GENERATED from {filename}" + + +def main(argv: Sequence[str]) -> int: + parser = argparse.ArgumentParser( + description="Renders a Jinja template from stdin to stdout" + ) + parser.parse_args(argv) # No arguments, but throws if arguments are provided + template_str = sys.stdin.read() + env = jinja2.Environment( + line_statement_prefix="#%", + line_comment_prefix="##", + ) + env.filters["format_each"] = format_each # type: ignore + tmpl = env.from_string(template_str) + s = tmpl.render(generated_file_notice=gen_warning) + sys.stdout.write(s) + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/src/neo/addressof.hpp b/src/neo/addressof.hpp index 694516e..ea56260 100644 --- a/src/neo/addressof.hpp +++ b/src/neo/addressof.hpp @@ -2,13 +2,7 @@ #include "./attrib.hpp" -// clang-format off -#if (NEO_HAS_BUILTIN(__builtin_addressof) || defined(_MSC_VER)) -#define HAS_ADDROF_INTRIN 1 -#endif -// clang-format on - -#ifndef HAS_ADDROF_INTRIN +#if !NEO_HAS_BUILTIN(__builtin_addressof) #include #endif @@ -20,7 +14,7 @@ namespace neo { */ template constexpr T* addressof(T& arg) noexcept { -#if HAS_ADDROF_INTRIN +#if NEO_HAS_BUILTIN(__builtin_addressof) return __builtin_addressof(arg); #else return std::addressof(arg); @@ -30,14 +24,10 @@ constexpr T* addressof(T& arg) noexcept { template const T& addressof(const T&&) = delete; -#if HAS_ADDROF_INTRIN +#if NEO_HAS_BUILTIN(__builtin_addressof) #define NEO_ADDRESSOF(X) __builtin_addressof((X)) #else #define NEO_ADDRESSOF(X) std::addressof((X)) #endif } // namespace neo - -#ifdef HAS_ADDROF_INTRIN -#undef HAS_ADDROF_INTRIN -#endif diff --git a/src/neo/attrib.hpp b/src/neo/attrib.hpp index 9be8965..e8966d4 100644 --- a/src/neo/attrib.hpp +++ b/src/neo/attrib.hpp @@ -73,6 +73,7 @@ #define NEO_MSVC_HAS_BUILTIN__is_unbounded_array #define NEO_MSVC_HAS_BUILTIN__is_union #define NEO_MSVC_HAS_BUILTIN__underlying_type +#define NEO_MSVC_HAS_BUILTIN__builtin_addressof #define NEO_MSVC_HAS_BUILTIN__make_integer_seq diff --git a/src/neo/channel.detail.hpp b/src/neo/channel.detail.hpp new file mode 100644 index 0000000..d5b5628 --- /dev/null +++ b/src/neo/channel.detail.hpp @@ -0,0 +1,442 @@ +#pragma once + +#include "./channel_fwd.hpp" + +#include +#include +#include +#include +#include + +#include +#include + +namespace neo::_channel_detail { + +// Information used to coordinate between nested channel coroutines +struct stack_resume_info { + std::exception_ptr thrown; + std::coroutine_handle<> co_handle; +}; + +// Used to extract the coroutine handle from a `from_channel` wrapper. +struct from_chan_coro_getter { + template + static auto getit(from_channel& from) noexcept { + return from._coro; + } +}; + +/** + * @brief Abstract base class for send/yield handling + * + * @tparam T + */ +template +class io_base { +public: + /** + * @brief Push the referred-to value to the handler. + */ + virtual void put(add_lvalue_reference_t>) = 0; +}; + +/** + * @brief Implements the return value aspect of channel + * + * @tparam Derived The derived promise type (CRTP) + */ +template +struct return_part; + +/** + * @brief Implements the yielding aspect channels. `T` must be `void` or an + * lvalue-reference type. This type may be empty. + * + * Derives from io_base. Defines a `get() -> nonvoid_t&` method. + */ +template +struct yield_io; + +/** + * @brief Implements the sending+resuming aspect for channels. `T` must be `void` + * or an lvalue-reference type. This type must be constructed with a coroutine + * handle. + * + * Derives from io_base. Defines a `get() -> nonvoid_t&` method. + */ +template +struct send_io; + +template +concept nested_channel_yield_compatible = requires { + // The type being send to the outer channel should be convertible to the type that the inner + // channel expects to be sent + requires convertible_to; + // The type yielded by the sub-channel must be convertible to the parent channel's yield type + requires convertible_to; + // Passing the yield/send values through should not construct any references to temporary + // objects: + requires not reference_constructible_from_temporary; + requires not reference_constructible_from_temporary; +}; + +/** + * @brief Promise type for channels + */ +template +class promise : public return_part> { + // The coroutine handle type for this promise + using handle_type = std::coroutine_handle; + + // Grant other promises access to our components, to allow updating the yield/send IO + template + friend class _channel_detail::promise; + + // The yield handler for this promise. + NEO_NO_UNIQUE_ADDRESS yield_io> _self_yielder; + // The send handler for this promise. We pass the handle to this coroutine so that + // the send_io can resume this coroutine when the caller sends on the channel. + send_io> _self_sender{handle_type::from_promise(*this)}; + + /** + * @brief Pointer to the active send-handler for the channel. + * + * In the non-recursive case, this pointer always points to our own send-handler. + * If the coroutine yields-from another channel<>, this pointer will be temporarily + * updated to point to the send-handler for that sub-channel. + * + * See `nested_awaiter` for where this pointer is manipulated. + */ + io_base>* _sender = &_self_sender; + /** + * @brief Pointer to the yield-handler for the channel. + * + * Like the send-handler, this usually points to our own yield handler, but it + * may be updated by a parent coroutine in `nested_awaiter`. + */ + io_base>* _yielder = &_self_yielder; + + /** + * @brief Pointer-to-pointer-to the root sender for the current channel + * stack. This pointer will be updated by calls to the nested_yielded, and + * is used to update the `_sender` pointer on the root channel when a sub-channel + * begins execution. + */ + io_base>** _root_sender_ptr = &_sender; + + /** + * @brief Information about the parent channel coroutine, if applicable. + * + * This pointer is only assigned by a parent coroutine in `nested_awaitable`. + */ + stack_resume_info* _parent = nullptr; + +public: + // Conversion helper for the channel + struct init { + // Coroutine handle for the channel + handle_type co; + }; + + constexpr init get_return_object() noexcept { return {handle_type::from_promise(*this)}; } + + // Always start the channel coroutine as suspended + std::suspend_always initial_suspend() const noexcept { return {}; } + + // Push a value into the channel, also resuming it + void send_value(nonvoid_t& arg) { this->_sender->put(arg); } + + /** + * @brief Obtain a reference to the yielded value. If `void`, then returns + * a `unit&` + */ + nonvoid_t& get_yielded() noexcept { + return static_cast&>(_self_yielder.get()); + } + + void unhandled_exception() { + if (this->_parent) { + // We are a sub-channel, and we want the parent coroutine to resume + // with the exception that we just caught. + this->_parent->thrown = std::current_exception(); + // Don't rethrow, just stop: + return; + } + // No parent coroutine is running, so re-throw into the resumer + throw; + } + + // An awaitable used at the end of a channel to optionally resume a parent + // channel, if present + struct parent_resumer { + promise& self; + + // We always suspend ourself + constexpr bool await_ready() const noexcept { return false; } + // Symmetric transfer to another coroutine: + constexpr std::coroutine_handle<> await_suspend(auto) const noexcept { + if (self._parent) { + // We are executing as part of a sub-channel. We want to resume + // the coroutine that started us + return self._parent->co_handle; + } + // We are not executing as a child, so run the noop coroutine, which + // will just immediately return to the resumer + return std::noop_coroutine(); + } + // This is never called, as we are done executing + void await_resume() const noexcept { std::terminate(); } + }; + + parent_resumer final_suspend() noexcept { return {*this}; } + + /** + * @brief Awaiter type generated by `co_yield` expressions. Unconditionally + * suspends the coroutine and stores a pointer to the yielded value in a place + * that is accessible to the caller + * + * @tparam YieldTmp The temporary object type used to store the yielded value. + * May be a reference. + */ + template + struct yield_awaiter { + promise& self; + YieldTmp yielded_value; + + constexpr bool await_ready() const noexcept { return false; } + + /// Upon resumption, return the sent value that caused the resume: + Send await_resume() const noexcept { + return static_cast>(self._self_sender.get()); + } + + // Upon suspend, store a pointer to the yielded value: + constexpr void await_suspend(auto) noexcept { self._yielder->put(yielded_value); } + }; + + /** + * @brief Yield a value. Primary overload. + * + * @param y A reference to the value being yielded. + * + * This function only records a reference to the yielded value, and does not + * copy/move the value. This relies on the compiler extending the lifetime of + * the yield operand to the full yield expression, allowing the reference to + * outlive the entire coroutine suspension that is caused by that `co_yield`. + * + * If the Yield type is a non-reference type, then this function + * accepts an rvalue-reference to the yield type, which may incur an automatic + * conversion at the yield site. If the Yield type is a reference type, then + * this function will accept exactly that reference type as an operand. + */ + yield_awaiter&> yield_value(nonvoid_t&& y) noexcept { + return {*this, y}; + } + + template + requires reference_constructible_from_temporary + [[deprecated( + "Your channel's yield-type is a reference type, but the operand of your `co_yield` " + "expression would bind a the yielded reference to a temporary. This is safe, but probably" + "a mistake.")]] void + yield_value(Arg&& arg) + = delete; + + /** + * @brief Yield with a possible conversion. + * + * @note This overload is only visible if Yield IS NOT a reference type. This + * makes two overloads of `yield_value` available: `yield_value(T&&)` and `yield_value(const + * T&)`, which allows the yielding of `T` values that will either move or copy as-needed. + * + * If Yield is an lvalue reference, then Yield&& will be an lvalue reference, and the requires + * constraint on this function will fail. + * + * This will always accept a reference-to-const of the underlying type, which + * results in allowing conversions to the yielded type + */ + constexpr yield_awaiter> yield_value(nonvoid_t const& y) noexcept + // This overload is only visible for non-lref types: + requires(not reference_type) + // We must be able to copy to the underlying type + and convertible_to const&, Yield> + { + // In this case, the yield_awaiter takes the yielded object by-value (using a copy), because + // we cannot reference-extend the object. + return {*this, y}; + } + + /** + * @brief Awaiter generated by `co_yield from_channel(...)`. + * + * This connects sub-channels to this channel and resumes them immediately. + * + * @tparam OtherCo The coroutine handle type used by the other channel. Note + * that the channel might not be equivalent to our own! + */ + template + struct nested_awaiter; + + template + struct nested_awaiter>> { + using OtherHandle = std::coroutine_handle>; + promise& self; + // coroutine handle for the sub-channel + OtherHandle child_co_handle; + // Resumption info that is used to coordinate with the sub-channel + stack_resume_info resume_info{}; + + // We are only done if the sub-channel is already done + constexpr bool await_ready() const noexcept { return child_co_handle.done(); } + + struct sender_link : io_base> { + io_base>* _send_child; + + void put(add_lvalue_reference_t> s) { _send_child->put(s); } + }; + + struct yielder_link : io_base> { + io_base>* _parent_yield; + + void put(nonvoid_t& s) { _parent_yield->put(s); } + }; + + sender_link _sender2{}; + yielder_link _yielder2{}; + + io_base>* + get_sender_link(io_base>* child_sender) { + if constexpr (weak_same_as) { + return child_sender; + } else { + _sender2._send_child = child_sender; + return &_sender2; + } + } + + io_base>* + get_yielder_link(io_base>* parent_yielder) { + if constexpr (weak_same_as) { + return parent_yielder; + } else { + _yielder2._parent_yield = parent_yielder; + return &_yielder2; + } + } + + // Suspension semantics for yielding-from sub-channels: + constexpr auto await_suspend(handle_type this_co) noexcept { + // The promise of the sub-channel: + auto& child_pr = child_co_handle.promise(); + // Connect the root send-handler for our own channel stack to the send-handler + // for the sub-channel. This ensures that when the resumer calls `send()` on this + // channel (or a parent thereof), the sent value will be immediately directed to the new + // leaf channel, and that leaf channel will be resumed instead of the suspended parent + // channels. + *self._root_sender_ptr = this->get_sender_link(child_pr._sender); + // Tell the sub-channel where the root sender-handler-pointer lives, in case it needs to + // spawn any sub-channels of its own: + child_pr._root_sender_ptr = self._root_sender_ptr; + // Tell the sub-channel ot use our the current yielder as its yielder. This may point to + // a yielder of a parent channel as well. + child_pr._yielder = this->get_yielder_link(self._yielder); + // Give the sub-channel a way to coordinate with this channel. + child_pr._parent = &resume_info; + // Tell the sub-channel our own coroutine handle so that it can resume us when it + // returns. + resume_info.co_handle = this_co; + // Symmetric transfer: Begin executing the subchannel + return child_co_handle; + } + + // Sub-channel returns: Now we return the return value from that channel from + // the `co_yield` expression itself. + constexpr OtherReturn await_resume() const { + // Re-connect the root sender to this channel now that it has become the leaf channel + // again. + *self._root_sender_ptr = &self._self_sender; + if (resume_info.thrown) { + // The subchannel threw an exception during execution, so we should rethrow it too + std::rethrow_exception(resume_info.thrown); + } + // Get the return value + return static_cast>( + child_co_handle.promise().get_returned()); + } + }; + + template + requires nested_channel_yield_compatible + auto yield_value(from_channel> from) { + auto other_co = from_chan_coro_getter::getit(from); + return nested_awaiter{*this, other_co}; + } +}; + +template +struct promise_base; + +template +struct return_part> { + using Derived = promise; + + optional _retval; + + constexpr Return& get_returned() noexcept { return *_retval; } + + template Arg> + constexpr void return_value(Arg&& arg) { + _retval.emplace(NEO_FWD(arg)); + } +}; + +template +struct return_part> { + constexpr void return_void() noexcept {} + constexpr unit get_returned() noexcept { return {}; } +}; + +template +struct send_io : io_base { + explicit send_io(std::coroutine_handle<> co) noexcept + : resumer(co) {} + add_pointer_t ptr; + std::coroutine_handle<> resumer; + + void put(Ref ref) { + ptr = NEO_ADDRESSOF(ref); + resumer.resume(); + } + Ref get() const noexcept { return *ptr; } +}; + +template +struct send_io : io_base { + explicit send_io(std::coroutine_handle<> co) noexcept + : resumer(co) {} + + std::coroutine_handle<> resumer; + static inline unit nil; + + void put(unit&) override { resumer.resume(); } + unit& get() const noexcept { return nil; } +}; + +template +struct yield_io : io_base { + add_pointer_t ptr; + void put(T ref) override { ptr = NEO_ADDRESSOF(ref); } + + T get() const noexcept { return *ptr; } +}; + +template +struct yield_io : io_base { + void put(unit&) override {} + + static inline unit nil; + unit& get() const noexcept { return nil; } +}; + +} // namespace neo::_channel_detail diff --git a/src/neo/channel.hpp b/src/neo/channel.hpp index 48228d7..4af3919 100644 --- a/src/neo/channel.hpp +++ b/src/neo/channel.hpp @@ -1,40 +1,73 @@ #pragma once -#include +#include "./channel.detail.hpp" #include -#include -#include +#include #include +#include #include -#include +#include namespace neo { +/** + * @brief A bidirectional communication channel coroutine type. + * + * The channel starts in a suspended state, and may be launched by calling `open()` to + * get a `channel_pipe`, or `begin()` to return an iterator (only available for some + * configurations of the channel). + * + * @tparam Yield The type that will be produced by the coroutine, accessed using the pipe's + * `current()`/`take_current()` method. + * @tparam Send The type that will be sent to the coroutine, delivered by the pipe `send` method, + * and the return value of plain `co_yield` expressions within the coroutine. + * @tparam Return The type that should be `co_returned` from the coroutine. Accessible + * from the invoker as the `return_value()` method on the channel pipe. + * + * Any of the above template parameters may be `void`, with the following notes: + * + * • If the `Yield` parameter is void, then the `co_yield` expressions must yield + * a literal zero "0", and the `current()` method will return void. + * • If the `Send` parameter is void, then the `co_yield` expression will have + * type `void`, and `send()` must be called with no arguments. + * • If the `Return` parameter is void, then the `return_value()` function will + * also have a return type of `void`. + * + * Channel coroutines may also co_yield other channels, using the `from_channel` + * wrapper. + */ template class channel { public: - using promise_type = _channel_detail::promise; - using send_type = Send; - using yield_type = Yield; - using return_type = Return; - - using pipe_type = channel_pipe; - -private: - template - friend class _channel_detail::promise; - - template - friend class from_channel; + /// The type given for the Yield template parameter + using yield_type = Yield; + /// The type given for the Send template parameter + using send_type = Send; + /// The type given for the Return template parameter + using return_type = Return; + // The promise type of the channel + using promise_type = _channel_detail::promise; - using handle_type = std::coroutine_handle; + /** + * @brief The type returned by `channel::open()`, used for communicating with + * the channel. + */ + using pipe_type = channel_pipe; public: + /** + * @brief Launch the channel and begin execution. + * + * The behavior of calling this function more than once is undefined + * + * @return pipe_type A new active channel pipe + */ pipe_type open() { // Initiate the channel: _coro.resume(); + // The channel is now paused and ready with its first value (or immediately done) return pipe_type(_coro); } @@ -61,8 +94,20 @@ class channel { return *this; } - constexpr from_channel operator~() noexcept; + /** + * @brief Return a from_channel that can be co_yielded to start a nested channel. + * + * See `from_channel` for more information. + */ + constexpr from_channel operator*() noexcept; + +private: + template + friend class from_channel; + using handle_type = std::coroutine_handle; + +public: class iterator { handle_type _coro; @@ -74,9 +119,7 @@ class channel { struct sender { handle_type co; - void operator=(typename promise_type::send_put send) const&& { - co.promise().send_value(NEO_FWD(send)); - } + void operator=(nonvoid_t&& send) const&& { co.promise().send_value(send); } }; public: @@ -118,102 +161,106 @@ class channel { constexpr std::default_sentinel_t end() const noexcept { return {}; } + constexpr channel(typename promise_type::init init) noexcept + : _coro(init.co) {} + private: handle_type _coro; - - constexpr explicit channel(handle_type h) noexcept - : _coro(h) {} }; +/** + * @brief Communication handle for a neo::channel + * + * Do not construct this directly. Use neo::channel::open to obtain an instance + * of this type. + */ template class channel_pipe { - using promise = _channel_detail::promise; - using handle_type = std::coroutine_handle; - handle_type _coro; - - friend class channel; - - explicit channel_pipe(handle_type co) - : _coro(co) {} public: - using send_type = Send; - using yield_type = Yield; + /// The type to send to the channel + using send_type = Send; + /// The type yielded by the channel + using yield_type = Yield; + /// The final result type of the channel using return_type = Return; - using send_put = promise::send_put; /** - * @brief Returns `true` if the channel has co_returned + * @brief Returns `true` if the channel has co_returned normally */ - constexpr bool done() const noexcept { return _coro.promise().has_returned(); } + constexpr bool done() const noexcept { return _coro.done(); } /** * @brief Obtain the most-recently yielded value from the channel. * - * This function will always return an lvalue-reference. Use take_current() - * to obtain the value from the coroutine casted to the true yield type. + * If `yield_type` is `void`, returns `void`. Otherwise, returns an lvalue-reference + * to the yielded value. + * + * @pre `not done()` */ constexpr add_lvalue_reference_t current() const noexcept { - return _coro.promise().get_yielded(); + return static_cast>(_coro.promise().get_yielded()); } /** - * @brief Take the current object yielded by the channel. + * @brief Take the current object yielded by the channel. May move-construct + * from the underlying object if the yield type is an object type * - * @return _types::yield_backward + * @pre `not done()` */ - constexpr add_rvalue_reference_t take_current() noexcept { + constexpr yield_type take_current() noexcept { return static_cast>(_coro.promise().get_yielded()); } /** - * @brief Send a value. This is the main overload + * @brief Send a value and resume the channel. * - * The type of the parameter depends on the template parameter for sending. - * If Send is void, this function is not available. + * Accepts an rvalue-reference to the send type. This overload is only + * available if the send type is not `void`. * - * @param arg The value to send + * @pre `not done()` */ - constexpr void send(send_put arg) - requires(not neo_is_void(send_type)) + constexpr void send(nonvoid_t&& arg) + requires(not void_type) { - _coro.promise().send_value(NEO_FWD(arg)); + _coro.promise().send_value(arg); } /** - * @brief Send a value with a possible conversion. - * - * @note This overload is only visible if Send IS NOT an lvalue-reference type. + * @brief Send a value with a possible conversion, and resume the channel * - * If Send is an lvalue reference, then Send&& will be an lvalue reference, and the requires - * constraint on this function will fail. + * @note This overload is only visible if Send IS NOT a reference type. * * This will always accept a reference-to-const of the underlying type, which * results in allowing conversions to the yielded type * * @param y * @return yield_awaiter> + * + * @pre `not done()` */ - constexpr void send(const_reference_t arg) - requires(not void_type) + constexpr void send(nonvoid_t const& arg) // Require that we are not sending lvalue-references: - and rvalue_reference_type> + requires(not reference_type) // Require that we can construct a send value from the const-reference: - and convertible_to, remove_cvref_t> + and convertible_to const&, send_type> { - remove_cvref_t x = NEO_FWD(arg); - _coro.promise().send_value(NEO_FWD(x)); + nonvoid_t tmp(arg); + _coro.promise().send_value(tmp); } /** - * @brief Send a void value (resumes the coroutine channel) + * @brief Send a void value and resume the channel * * This overload is only visible if Send is `void` + * + * @pre `not done()` */ constexpr void send() requires void_type { - _coro.promise().send_value(nullptr); + unit nil; + _coro.promise().send_value(nil); } /** @@ -221,293 +268,73 @@ class channel_pipe { * * If the Return type is void, this function returns void. Otherwise, * this function will always return an lvalue-reference. + * + * @pre `done()` */ constexpr add_lvalue_reference_t return_value() const noexcept { - return _coro.promise().get_returned(); + return static_cast>(_coro.promise().get_returned()); } /** * @brief Take the final return value from the coroutine. * - * This returns exactly yield_type, which may be an rvalue + * This returns exactly yield_type, which may be an rvalue. + * + * @pre `done()` */ constexpr return_type take_return_value() noexcept { - return _coro.promise().take_return_value(); + return static_cast>(_coro.promise().get_returned()); } + +private: + // Promise type for the coroutine + using promise = _channel_detail::promise; + // Coroutine handle type for the channel + using handle_type = std::coroutine_handle; + + // Allow our channel to call our constructor + friend channel; + + /** + * @brief Construct a new channel pipe object from a channel's coroutine handle + */ + constexpr explicit channel_pipe(handle_type co) noexcept + : _coro(co) {} + +private: + // The coroutine handle for the channel + handle_type _coro; }; +/** + * @brief Within a channel coroutine, allows yielding control to a sub-channel. + * + * Within a channel coroutine, a `co_yield` expression may accept a `from_channel` + * as an operand, which tells the coroutine to suspend and delegate further + * execution to the new channel. Values sent/yielded into the channel will be + * piped into the child coroutine until it returns. The return value from the + * child coroutine is the result value of the `co_yield` expression in the + * parent. + */ template class from_channel { // The wrapped channel coroutine typename remove_cvref_t::handle_type _coro; - template - friend struct _channel_detail::promise_base; + friend _channel_detail::from_chan_coro_getter; public: explicit from_channel(const C& c) noexcept : _coro(c._coro) {} }; +// CTAD for from_channnel template explicit from_channel(C const&) -> from_channel; template -constexpr from_channel> channel::operator~() noexcept { +constexpr from_channel> channel::operator*() noexcept { return from_channel(*this); } -namespace _channel_detail { - -template -struct promise_return { - using return_get = ReturnVal&; - using return_take = ReturnVal; - neo::nano_opt _return_value; - bool _did_throw = false; - template U> - constexpr void return_value(U&& arg) noexcept(nothrow_constructible_from) { - _return_value.emplace(NEO_MOVE(arg)); - } - constexpr bool has_returned() const noexcept { return _return_value.has_value() or _did_throw; } - constexpr ReturnVal& get_returned() noexcept { return _return_value.get(); } - constexpr ReturnVal take_return_value() noexcept { return NEO_MOVE(_return_value.get()); } -}; - -template -struct promise_return { - using return_get = ReturnRef&; - using return_take = ReturnRef&&; - neo::optional _return_value; - bool _did_throw = false; - template U> - constexpr void return_value(U&& arg) noexcept(nothrow_constructible_from) { - _return_value = arg; - } - constexpr bool has_returned() const noexcept { return !!_return_value or _did_throw; } - constexpr return_get get_returned() const noexcept { - return static_cast(*_return_value); - } - constexpr return_take take_return_value() const noexcept { - return static_cast(*_return_value); - } -}; - -template <> -struct promise_return { - bool _did_return = false; - bool _did_throw = false; - constexpr void return_void() noexcept { _did_return = true; } - constexpr bool has_returned() const noexcept { return _did_return or _did_throw; } - constexpr void get_returned() noexcept {} - constexpr void take_return_value() noexcept {} - using return_get = void; - using return_take = void; -}; - -template -struct channel_box { - using put_type = T&&; - using get_type = T&; - using take_type = T; - - remove_reference_t* _ptr = nullptr; - - constexpr void put(put_type p) { _ptr = NEO_ADDRESSOF(p); } - constexpr get_type get() const noexcept { return static_cast(*_ptr); } - constexpr take_type take() const noexcept { return static_cast(*_ptr); } -}; - -template <> -struct channel_box { - using put_type = decltype(nullptr); - using get_type = void; - using take_type = void; - - constexpr void put(put_type) {} - constexpr void get() const noexcept {} - constexpr void take() const noexcept {} -}; - -template <> -struct channel_box : channel_box {}; - -template -struct promise_base { - using yield_box = channel_box; - using send_box = channel_box; - using yield_put = yield_box::put_type; - using yield_get = yield_box::get_type; - using send_put = send_box::put_type; - - virtual std::coroutine_handle<> do_get_handle() noexcept = 0; - - NEO_NO_UNIQUE_ADDRESS yield_box _yield_box; - NEO_NO_UNIQUE_ADDRESS send_box _send_box; - - // In the beginning, we believe that we are the leaf and the root channel in the chain: - promise_base* _leaf = this; - promise_base* _root = this; - - void connect_leaf(promise_base* leaf) { - _leaf = leaf; - _leaf->_root = this; - } - - // Keep track of what we are doing here - struct parent_resume_info { - std::exception_ptr thrown; - std::coroutine_handle<> resume; - }; - - parent_resume_info* _parent = nullptr; - - // Awaiter for inner channels: - template - struct nested_awaiter { - promise_base& self; - // The inner channel that we are waiting for - Promise& child; - parent_resume_info info{}; - - constexpr bool await_ready() const noexcept { return child.has_returned(); } - constexpr auto await_suspend(std::coroutine_handle<> this_co) noexcept { - self._root->connect_leaf(&child); - child._parent = &info; - info.resume = this_co; - return std::coroutine_handle::from_promise(child); - } - - constexpr Ret await_resume() const { - self._root->connect_leaf(&self); - if (info.thrown) { - std::rethrow_exception(info.thrown); - } - return child.take_return_value(); - } - }; - - template ::promise_type> - requires derived_from - constexpr auto yield_value(from_channel ch) { - Promise& pr = ch._coro.promise(); - return nested_awaiter::return_type>{*this, pr}; - } - - struct parent_resumer { - promise_base& self; - - constexpr bool await_ready() const noexcept { return false; } - constexpr std::coroutine_handle<> await_suspend(auto) const noexcept { - if (self._parent) { - return self._parent->resume; - } - return std::noop_coroutine(); - } - void await_resume() const noexcept { std::terminate(); } - }; - - constexpr parent_resumer final_suspend() noexcept { return {*this}; } - - std::suspend_always initial_suspend() const noexcept { return {}; } - - /** - * @brief Sends a value and resumes the innermost channel - * - * @return true If the channel returned - * @return false Otherwise - */ - constexpr void send_value(send_put arg) { - // We're the leaf channel - _leaf->_send_box.put(NEO_FWD(arg)); - _leaf->do_get_handle().resume(); - } - - /** - * @brief Obtain the yielded value - */ - constexpr yield_get get_yielded() const noexcept { return _leaf->_yield_box.get(); } - - // Awaiter for regular yield expressions - template - struct yield_awaiter { - promise_base& self; - Store _store; - - constexpr bool await_ready() const noexcept { return false; } - constexpr typename send_box::take_type await_resume() const noexcept { - // Return the value that was sent to the coroutine upon resume: - return self._send_box.take(); - } - - constexpr void await_suspend(auto) noexcept { self._yield_box.put(NEO_FWD(_store)); } - }; - - /** - * @brief Yield a value. This is the main overload - * - * The type of the parameter depends on the template parameter for yielding. - * If Yield is void, yield_forward is nullptr_t, otherwise it is Yield&& - * - * @param y The value to yield - * @return yield_awaiter - */ - constexpr yield_awaiter yield_value(yield_put y) noexcept { - return {*this, NEO_FWD(y)}; - } - - /** - * @brief Yield with a possible conversion. - * - * @note This overload is only visible if Yield IS NOT an lvalue-reference type. - * - * If Yield is an lvalue reference, then Yield&& will be an lvalue reference, and the requires - * constraint on this function will fail. - * - * This will always accept a reference-to-const of the underlying type, which - * results in allowing conversions to the yielded type - * - * @param y - * @return yield_awaiter> - */ - constexpr yield_awaiter> - yield_value(const_reference_t y) noexcept - // This overload is only visible for non-lref types: - requires rvalue_reference_type - // We must be able to convert the forwarding reference to the underlying type: - and convertible_to, remove_cvref_t> - { - return {*this, NEO_FWD(y)}; - } -}; - -template -class promise : public promise_base, // - public promise_return { - /// The channel associated with this promise - using channel_type = channel; - - std::coroutine_handle<> do_get_handle() noexcept override { - return std::coroutine_handle::from_promise(*this); - } - -public: - void unhandled_exception() { - if (this->_parent) { - this->_parent->thrown = std::current_exception(); - return; - } - this->_did_throw = true; - throw; - } - - constexpr channel_type get_return_object() noexcept { - return channel_type{std::coroutine_handle::from_promise(*this)}; - } - - constexpr bool did_throw() const noexcept { return this->_did_throw; } -}; - -} // namespace _channel_detail - } // namespace neo diff --git a/src/neo/channel.test.cpp b/src/neo/channel.test.cpp index 8445350..d15f25d 100644 --- a/src/neo/channel.test.cpp +++ b/src/neo/channel.test.cpp @@ -18,15 +18,50 @@ channel int_chan() { } TEST_CASE("Simple channel") { - auto ch = int_chan(); - auto io = ch.open(); - CHECK(io.current() == 21); + auto ch = int_chan(); + auto ch1 = NEO_MOVE(ch); + auto io = ch1.open(); + auto cur = io.current(); + CHECK(cur == 21); int i = 42; io.send(i); CHECK(io.done()); io.return_value(); } +channel only_yields_chan() { + co_yield 42; + co_yield 1729; +} + +TEST_CASE("Channel that only yields") { + auto ch = only_yields_chan(); + auto io = ch.open(); + CHECK(io.current() == 42); + io.send(); + CHECK(io.current() == 1729); + io.send(); + CHECK(io.done()); + io.return_value(); +} + +channel only_sends_chan(bool& flag) { + auto n = co_yield 0; + CHECK(n == 42); + flag = true; +} + +TEST_CASE("Channel that only receives values") { + bool did_run = false; + auto ch = only_sends_chan(did_run); + CHECK_FALSE(did_run); + auto io = ch.open(); + CHECK_FALSE(did_run); + io.send(42); + CHECK(io.done()); + CHECK(did_run); +} + channel ret_int_chan() { co_yield 0; // Should not compile: @@ -43,9 +78,26 @@ TEST_CASE("Non-void return") { CHECK(io.return_value() == 42); } +channel yields_lvalue_expr() { + int foo = 1729; + // Yield an lvalue-reference. This will copy the lvalue + co_yield foo; + const int bar = 42; + // Yielding a const& is also good. + co_yield bar; +} + +TEST_CASE("Yielding lvalue copies lvalues") { + auto ch = yields_lvalue_expr(); + auto io = ch.open(); + CHECK(io.current() == 1729); + io.send(); + CHECK(io.current() == 42); +} + static int global_int = 0; channel ret_int2_chan() { - co_yield 0; + co_yield {}; // Should not compile: // co_return 51; global_int = 42; @@ -65,7 +117,7 @@ channel ret_int3_chan() { global_int = 71; co_yield global_int; // Should not compile: - // co_yield 0; + // co_yield 71; global_int = 42; co_return global_int; } @@ -80,7 +132,10 @@ TEST_CASE("Reference yield") { CHECK(io.return_value() == 42); } -channel inner() { co_yield 31; } +channel inner() { + co_yield 31; + co_yield 8; +} channel outer() { co_yield global_int; co_yield from_channel(inner()); @@ -96,9 +151,36 @@ TEST_CASE("Nested yield") { REQUIRE_FALSE(io.done()); CHECK(io.current() == 31); io.send(); + CHECK(io.current() == 8); + io.send(); CHECK(io.done()); } +channel more_outerer() { + co_yield 4; + co_yield *outer(); + co_yield -4; +} + +TEST_CASE("Deeper nested yield") { + global_int = 94; + auto ch = more_outerer(); + auto io = ch.open(); + REQUIRE_FALSE(io.done()); + CHECK(io.current() == 4); + io.send(); + REQUIRE_FALSE(io.done()); + CHECK(io.current() == 94); + io.send(); + REQUIRE_FALSE(io.done()); + CHECK(io.current() == 31); + io.send(); + CHECK(io.current() == 8); + io.send(); + REQUIRE_FALSE(io.done()); + CHECK(io.current() == -4); +} + channel inner_with_str() { co_yield 31; co_return "Howdy"; @@ -177,9 +259,9 @@ channel<> maybe_throw(bool do_throw) { } channel<> inner_loop() { std::vector vec(1024); - co_yield ~maybe_throw(false); - co_yield ~maybe_throw(true); - co_yield ~maybe_throw(false); + co_yield *maybe_throw(false); + co_yield *maybe_throw(true); + co_yield *maybe_throw(false); } channel<> outer_loop() { @@ -203,7 +285,7 @@ channel deep_channel(int layers) { CHECK(got == 1729); } else { co_yield layers; - co_yield ~deep_channel(layers - 1); + co_yield *deep_channel(layers - 1); co_yield layers; } } @@ -231,7 +313,7 @@ channel deep_return(int n, int top) { if (n == 0) { co_return top; } - co_return co_yield ~deep_return(n - 1, top); + co_return co_yield *deep_return(n - 1, top); } TEST_CASE("Deep return") { @@ -295,16 +377,62 @@ neo::channel inner_throws() { neo::channel outer_catches() { try { - co_yield ~inner_throws(); + co_yield *inner_throws(); FAIL("Child did not throw, but we expected it"); } catch (std::runtime_error const&) { co_return; } } -neo::channel outer_unaware() { co_yield ~outer_catches(); } +neo::channel outer_unaware() { co_yield *outer_catches(); } TEST_CASE("Nested throw") { auto ch = outer_unaware(); CHECK_NOTHROW(ch.open()); -} \ No newline at end of file +} + +struct ref_conversion { + static channel get_strings() { + std::string s = "Joe"; + co_yield s; + } + static channel get_string_values() { + co_yield "value-string"; // + } + static channel get_cstrings() { + co_yield "c-string"; // + } + static channel get_cstrings_cref() { + co_yield "c-string-cref"; // + } + static channel get_integers() { + int i = 21; + co_yield i; + } + static channel get_strings_const() { + std::string s = "Hello"; + co_yield s; + auto co = get_strings(); // Adds const + //* Should not compile: All will create a temporary-bound reference: + // co_yield *get_cstrings(); + // co_yield *get_cstrings_cref(); + // co_yield *get_string_values(); + //* Should not compile: Cannot convert an int& to a const std::string& + // co_yield *get_integers(); + //* Should not compile: Would create a temporary-bound reference from the string literal + // co_yield "bad"; + co_yield *co; + s = "fin"; + co_yield s; + } +}; + +TEST_CASE("Reference conversion") { + auto ch = ref_conversion::get_strings_const(); + auto io = ch.open(); + CHECK(io.current() == "Hello"); + io.send(); + CHECK(io.current() == "Joe"); + io.send(); + CHECK(io.current() == "fin"); +} diff --git a/src/neo/channel_fwd.hpp b/src/neo/channel_fwd.hpp index eddb00f..39b2e8c 100644 --- a/src/neo/channel_fwd.hpp +++ b/src/neo/channel_fwd.hpp @@ -2,28 +2,6 @@ namespace neo { -/** - * @brief A bidirectional communication channel coroutine type. - * - * @tparam Yield The type that will be produced by the coroutine, accessed using the `current()` - * method. - * @tparam Send The type that will be sent to the coroutine, delivered by the `send` method, and - * the return value of plain co_yield expressions - * @tparam Return The type that should be co_returned from the coroutine. Accessible - * from the invoker as the `return_value()` method. - * - * Any of the above template parameters may be `void`, with the following notes: - * - * • If the `Yield` parameter is void, then the `co_yield` expressions must yield - * a literal zero "0", and the `current()` method will return void. - * • If the `Send` parameter is void, then the `co_yield` expression will have - * type `void`, and `send()` must be called with no arguments. - * • If the `Return` parameter is void, then the `return_value()` function will - * also have a return type of `void`. - * - * Channel coroutines may also co_yield other channels, using the `from_channel` - * wrapper. - */ template class channel; @@ -43,14 +21,4 @@ class channel_pipe; template class from_channel; -namespace _channel_detail { - -template -class promise; - -template -struct promise_base; - -} // namespace _channel_detail - } // namespace neo diff --git a/src/neo/compare.hpp b/src/neo/compare.hpp new file mode 100644 index 0000000..5251b3f --- /dev/null +++ b/src/neo/compare.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "neo/attrib.hpp" +#include "neo/declval.hpp" +#include + +#include + +namespace neo { + +struct synth_three_way_fn { + template U> + NEO_ALWAYS_INLINE constexpr std::compare_three_way_result_t + operator()(const T& t, const U& u) const noexcept { + return t <=> u; + } + + template + requires(not three_way_comparable_with) + constexpr std::weak_ordering operator()(const T& t, const T& u) noexcept + requires requires { + { t < u } -> simple_boolean; + { u < t } -> simple_boolean; + } + { + if (t < u) { + return std::weak_ordering::less; + } else if (u < t) { + return std::weak_ordering::greater; + } + return std::weak_ordering::equivalent; + } +}; + +/** + * @brief A binary-invocable object that performs an effective three-way comparison + * between two objects of arbitrary type. It is only requires that the objects + * be less-than comparable. + * + * If a full `operator<=>` is available, it will be used, otherwise a `std::weak_ordering` + * will be generated by two calls to `operator<`. + * + * Based on the exposition-only `synth-three-way` used throughout the standard library. + */ +inline constexpr synth_three_way_fn synth_three_way; + +template +using synth_three_way_result_t + = decltype(synth_three_way(NEO_DECLVAL(T const&), NEO_DECLVAL(U const&))); + +} // namespace neo \ No newline at end of file diff --git a/src/neo/concepts.hpp b/src/neo/concepts.hpp index 64a8a68..fed9f00 100644 --- a/src/neo/concepts.hpp +++ b/src/neo/concepts.hpp @@ -2,6 +2,7 @@ #include "./fwd.hpp" #include "./invoke.hpp" +#include "./swap.hpp" #include "./type_traits.hpp" #include "./version.hpp" @@ -44,7 +45,12 @@ concept destructible = requires { template concept constructible_from = destructible - and requires(Args&&... args) { T(NEO_FWD(args)...); } + and requires(Args&&... args) { T((Args&&)(args)...); } + #if NEO_HAS_BUILTIN(__is_constructible) + and __is_constructible(T, Args...) + #else + and std::is_constructible_v + #endif ; /// Check whether one can static_cast(From) @@ -249,7 +255,9 @@ concept swappable_with = detail::swappable_impl; * @brief Test whether a type is swappable with itself via std::ranges::swap */ template -concept swappable = detail::can_std_ranges_swap; +concept swappable = requires(T& t) { + neo::swap(t, t); +} or detail::can_std_ranges_swap; namespace detail { @@ -408,9 +416,20 @@ concept nothrow_constructible_from = #endif ; +template +concept move_assignable = + move_constructible + and assignable_from; + +template +concept copy_assignable = + move_assignable + and copy_constructible + and assignable_from; + template concept trivially_constructible = - constructible_from + nothrow_constructible_from and neo_is_trivially_constructible(T, Args...); template @@ -428,15 +447,36 @@ concept trivially_assignable = assignable_from and neo_is_trivially_assignable(To, From); +template +concept trivially_move_constructible = + move_constructible + and trivially_constructible; + +template +concept trivially_copy_constructible = + copy_constructible + and trivially_constructible; + +template +concept trivially_copy_assignable = + copy_assignable + and trivially_assignable; + +template +concept trivially_move_assignable = + move_assignable + and trivially_assignable; + template concept trivially_movable = movable - and trivially_constructible + and trivially_move_constructible and trivially_assignable; template concept trivially_copyable = copyable + and trivially_copy_constructible and trivially_movable and neo_is_trivially_copyayable(T) ; @@ -451,17 +491,55 @@ concept nothrow_invocable = { neo::invoke(NEO_FWD(fn), NEO_FWD(args)...) } noexcept; }; -template -concept move_assignable = - move_constructible - and assignable_from; +namespace detail { template -concept copy_assignable = - move_assignable - and copy_constructible - and assignable_from; +struct narrowing_conversion_helper { + T one[1]; +}; + +} // namespace detail + +/** + * @brief Check that `From` is convertible to `To` without causing built-in + * narrowing. + */ +template +concept non_narrowing_convertible_to = + convertible_to + and requires(From&& from) { + // This expression will be invalid if the conversion of `From` to `To` + // causes narrowing, because such conversion appears within a braced initializer + detail::narrowing_conversion_helper>{{NEO_FWD(from)}}; + }; // clang-format on +namespace detail { + +template +concept best_guest_ref_from_tmp = + // If we can convert From* to Reference*, then there's a safe derived->base conversion + // that will not create a temporary + not convertible_to, add_pointer_t> + // If we can convert to the reference' value type, then a conversion might occur + and constructible_from, From> + // And if a reference can bind to an rvalue of the value type, then that's going to + // be the temporary binding we want to avoid + and constructible_from>>; + +} // namespace detail + +#if NEO_HAS_BUILTIN(__reference_constructs_from_temporary) +template +concept reference_constructible_from_temporary + = __reference_constructs_from_temporary(Reference, From); +#else +template +concept reference_constructible_from_temporary // + = reference_type // + and constructible_from // + and detail::best_guest_ref_from_tmp; +#endif + } // namespace neo diff --git a/src/neo/concepts.test.cpp b/src/neo/concepts.test.cpp index 0db2f1e..00e61ca 100644 --- a/src/neo/concepts.test.cpp +++ b/src/neo/concepts.test.cpp @@ -179,4 +179,24 @@ std::false_type test_trivially_copyable_subsume(T); static_assert(decltype(test_trivially_copyable_subsume(5))::value); +static_assert(non_narrowing_convertible_to); +static_assert(not non_narrowing_convertible_to); +static_assert(non_narrowing_convertible_to); +static_assert(not non_narrowing_convertible_to); +static_assert(not non_narrowing_convertible_to); +static_assert(non_narrowing_convertible_to); + static_assert(destructible); + +TEST_CASE("reference_constructible_from_temporary") { + STATIC_REQUIRE(not reference_constructible_from_temporary); + STATIC_REQUIRE(not reference_constructible_from_temporary); + STATIC_REQUIRE(not reference_constructible_from_temporary); + STATIC_REQUIRE(not reference_constructible_from_temporary); + STATIC_REQUIRE(not reference_constructible_from_temporary); + STATIC_REQUIRE(reference_constructible_from_temporary); + STATIC_REQUIRE(reference_constructible_from_temporary); + STATIC_REQUIRE(reference_constructible_from_temporary); + STATIC_REQUIRE(not reference_constructible_from_temporary); + STATIC_REQUIRE(not reference_constructible_from_temporary); +} diff --git a/src/neo/constexpr_union.hpp b/src/neo/constexpr_union.hpp new file mode 100644 index 0000000..2021682 --- /dev/null +++ b/src/neo/constexpr_union.hpp @@ -0,0 +1,16139 @@ +#pragma once + +// clang-format off + +// d8888b. .d88b. d8b db .d88b. d888888b d88888b d8888b. d888888b d888888b +// 88 `8D .8P Y8. 888o 88 .8P Y8. `~~88~~' 88' 88 `8D `88' `~~88~~' +// 88 88 88 88 88V8o 88 88 88 88 88ooooo 88 88 88 88 +// 88 88 88 88 88 V8o88 88 88 88 88~~~~~ 88 88 88 88 +// 88 .8D `8b d8' 88 V888 `8b d8' 88 88. 88 .8D .88. 88 +// Y8888D' `Y88P' VP V8P `Y88P' YP Y88888P Y8888D' Y888888P YP + +// This file was GENERATED from src/neo/constexpr_union.hpp.jinja + +#include +#include +#include +#include +#include +#include + +#include // std::construct_at + +namespace neo { + +/** + * @brief A variadic union template that is default-constructible and `constexpr`-ready. + * + * Defines three member function templates: + * + * - `get() -> nth_type [const] [&|&&]` obtain a reference to the `Nth` union member. + * - `construct(auto&&...) -> nth_type&` activate the `Nth` union member by calling + * the constructor with the given arguments. No other union members are modified. + * - `destroy() -> void` - Destroy the `Nth` union member by calling its destructor. + * + * Every specialization of `constexpr_union` constains a `nil` alternative which is + * activated upon default-construction of the union. The names of the variadic members are + * the zero-based index of the member with an underscore prefix (e.g. `_0`, `_1`, `_2`, `_3`). + * To access the `Nth` member generically, use the `get()` member function template, which + * returns a reference to that member with the cvref-qualifiers of the instance used to call the + * `get` member. To get the `Nth` type of the union, use the `nth_type` member alias + * template. + * + * The union is not a "`variant`"": it is up to the user to track the active member and + * to correctly call the constructors/destructors when needed. The sole purpose of + * this class template is to simplify the implementation of `variant`/`optional`-style + * class templates. + * + * Because of the implicit `nil` member, a `constexpr_union` can be used as storage + * for an optional `T`, with the `nil` member acting as a the "null" state. + * + * All union members are marked with `[[no_uninque_address]]`. + * + * @tparam Ts... The alternative of the union. Must not be empty. + */ +template +union constexpr_union; + +namespace detail { + +template +concept all_trivially_destructible = + (neo_is_trivially_destructible(Ts) and ... and true); + +template +NEO_ALWAYS_INLINE constexpr Ret get_member(Onion&& on) noexcept { + if constexpr (N == 0) return static_cast(on._0); + if constexpr (N == 1) return static_cast(on._1); + if constexpr (N == 2) return static_cast(on._2); + if constexpr (N == 3) return static_cast(on._3); + if constexpr (N == 4) return static_cast(on._4); + if constexpr (N == 5) return static_cast(on._5); + if constexpr (N == 6) return static_cast(on._6); + if constexpr (N == 7) return static_cast(on._7); + if constexpr (N == 8) return static_cast(on._8); + if constexpr (N == 9) return static_cast(on._9); + if constexpr (N == 10) return static_cast(on._10); + if constexpr (N == 11) return static_cast(on._11); + if constexpr (N == 12) return static_cast(on._12); + if constexpr (N == 13) return static_cast(on._13); + if constexpr (N == 14) return static_cast(on._14); + if constexpr (N == 15) return static_cast(on._15); + if constexpr (N == 16) return static_cast(on._16); + if constexpr (N == 17) return static_cast(on._17); + if constexpr (N == 18) return static_cast(on._18); + if constexpr (N == 19) return static_cast(on._19); + if constexpr (N == 20) return static_cast(on._20); + if constexpr (N == 21) return static_cast(on._21); + if constexpr (N == 22) return static_cast(on._22); + if constexpr (N == 23) return static_cast(on._23); + if constexpr (N == 24) return static_cast(on._24); + if constexpr (N == 25) return static_cast(on._25); + if constexpr (N == 26) return static_cast(on._26); + if constexpr (N == 27) return static_cast(on._27); + if constexpr (N == 28) return static_cast(on._28); + if constexpr (N == 29) return static_cast(on._29); + if constexpr (N == 30) return static_cast(on._30); + if constexpr (N == 31) return static_cast(on._31); + if constexpr (N == 32) return static_cast(on._32); + if constexpr (N == 33) return static_cast(on._33); + if constexpr (N == 34) return static_cast(on._34); + if constexpr (N == 35) return static_cast(on._35); + if constexpr (N == 36) return static_cast(on._36); + if constexpr (N == 37) return static_cast(on._37); + if constexpr (N == 38) return static_cast(on._38); + if constexpr (N == 39) return static_cast(on._39); + if constexpr (N == 40) return static_cast(on._40); + if constexpr (N == 41) return static_cast(on._41); + if constexpr (N == 42) return static_cast(on._42); + if constexpr (N == 43) return static_cast(on._43); + if constexpr (N == 44) return static_cast(on._44); + if constexpr (N == 45) return static_cast(on._45); + if constexpr (N == 46) return static_cast(on._46); + if constexpr (N == 47) return static_cast(on._47); + if constexpr (N == 48) return static_cast(on._48); + if constexpr (N == 49) return static_cast(on._49); + if constexpr (N == 50) return static_cast(on._50); + if constexpr (N == 51) return static_cast(on._51); + if constexpr (N == 52) return static_cast(on._52); + if constexpr (N == 53) return static_cast(on._53); + if constexpr (N == 54) return static_cast(on._54); + if constexpr (N == 55) return static_cast(on._55); + if constexpr (N == 56) return static_cast(on._56); + if constexpr (N == 57) return static_cast(on._57); + if constexpr (N == 58) return static_cast(on._58); + if constexpr (N == 59) return static_cast(on._59); + if constexpr (N == 60) return static_cast(on._60); + if constexpr (N == 61) return static_cast(on._61); + if constexpr (N == 62) return static_cast(on._62); + if constexpr (N == 63) return static_cast(on._63); + if constexpr (N == 64) return static_cast(on._64); + if constexpr (N == 65) return static_cast(on._65); + if constexpr (N == 66) return static_cast(on._66); + if constexpr (N == 67) return static_cast(on._67); + if constexpr (N == 68) return static_cast(on._68); + if constexpr (N == 69) return static_cast(on._69); + if constexpr (N == 70) return static_cast(on._70); + if constexpr (N == 71) return static_cast(on._71); + if constexpr (N == 72) return static_cast(on._72); + if constexpr (N == 73) return static_cast(on._73); + if constexpr (N == 74) return static_cast(on._74); + if constexpr (N == 75) return static_cast(on._75); + if constexpr (N == 76) return static_cast(on._76); + if constexpr (N == 77) return static_cast(on._77); + if constexpr (N == 78) return static_cast(on._78); + if constexpr (N == 79) return static_cast(on._79); + if constexpr (N == 80) return static_cast(on._80); + if constexpr (N == 81) return static_cast(on._81); + if constexpr (N == 82) return static_cast(on._82); + if constexpr (N == 83) return static_cast(on._83); + if constexpr (N == 84) return static_cast(on._84); + if constexpr (N == 85) return static_cast(on._85); + if constexpr (N == 86) return static_cast(on._86); + if constexpr (N == 87) return static_cast(on._87); + if constexpr (N == 88) return static_cast(on._88); + if constexpr (N == 89) return static_cast(on._89); + if constexpr (N == 90) return static_cast(on._90); + if constexpr (N == 91) return static_cast(on._91); + if constexpr (N == 92) return static_cast(on._92); + if constexpr (N == 93) return static_cast(on._93); + if constexpr (N == 94) return static_cast(on._94); + if constexpr (N == 95) return static_cast(on._95); + if constexpr (N == 96) return static_cast(on._96); + if constexpr (N == 97) return static_cast(on._97); + if constexpr (N == 98) return static_cast(on._98); + if constexpr (N == 99) return static_cast(on._99); +} + +template +NEO_ALWAYS_INLINE constexpr auto construct_member(Onion& on, Args&&... args) { + if constexpr (N == 0) return std::construct_at(NEO_ADDRESSOF(on._0), static_cast(args)...); + if constexpr (N == 1) return std::construct_at(NEO_ADDRESSOF(on._1), static_cast(args)...); + if constexpr (N == 2) return std::construct_at(NEO_ADDRESSOF(on._2), static_cast(args)...); + if constexpr (N == 3) return std::construct_at(NEO_ADDRESSOF(on._3), static_cast(args)...); + if constexpr (N == 4) return std::construct_at(NEO_ADDRESSOF(on._4), static_cast(args)...); + if constexpr (N == 5) return std::construct_at(NEO_ADDRESSOF(on._5), static_cast(args)...); + if constexpr (N == 6) return std::construct_at(NEO_ADDRESSOF(on._6), static_cast(args)...); + if constexpr (N == 7) return std::construct_at(NEO_ADDRESSOF(on._7), static_cast(args)...); + if constexpr (N == 8) return std::construct_at(NEO_ADDRESSOF(on._8), static_cast(args)...); + if constexpr (N == 9) return std::construct_at(NEO_ADDRESSOF(on._9), static_cast(args)...); + if constexpr (N == 10) return std::construct_at(NEO_ADDRESSOF(on._10), static_cast(args)...); + if constexpr (N == 11) return std::construct_at(NEO_ADDRESSOF(on._11), static_cast(args)...); + if constexpr (N == 12) return std::construct_at(NEO_ADDRESSOF(on._12), static_cast(args)...); + if constexpr (N == 13) return std::construct_at(NEO_ADDRESSOF(on._13), static_cast(args)...); + if constexpr (N == 14) return std::construct_at(NEO_ADDRESSOF(on._14), static_cast(args)...); + if constexpr (N == 15) return std::construct_at(NEO_ADDRESSOF(on._15), static_cast(args)...); + if constexpr (N == 16) return std::construct_at(NEO_ADDRESSOF(on._16), static_cast(args)...); + if constexpr (N == 17) return std::construct_at(NEO_ADDRESSOF(on._17), static_cast(args)...); + if constexpr (N == 18) return std::construct_at(NEO_ADDRESSOF(on._18), static_cast(args)...); + if constexpr (N == 19) return std::construct_at(NEO_ADDRESSOF(on._19), static_cast(args)...); + if constexpr (N == 20) return std::construct_at(NEO_ADDRESSOF(on._20), static_cast(args)...); + if constexpr (N == 21) return std::construct_at(NEO_ADDRESSOF(on._21), static_cast(args)...); + if constexpr (N == 22) return std::construct_at(NEO_ADDRESSOF(on._22), static_cast(args)...); + if constexpr (N == 23) return std::construct_at(NEO_ADDRESSOF(on._23), static_cast(args)...); + if constexpr (N == 24) return std::construct_at(NEO_ADDRESSOF(on._24), static_cast(args)...); + if constexpr (N == 25) return std::construct_at(NEO_ADDRESSOF(on._25), static_cast(args)...); + if constexpr (N == 26) return std::construct_at(NEO_ADDRESSOF(on._26), static_cast(args)...); + if constexpr (N == 27) return std::construct_at(NEO_ADDRESSOF(on._27), static_cast(args)...); + if constexpr (N == 28) return std::construct_at(NEO_ADDRESSOF(on._28), static_cast(args)...); + if constexpr (N == 29) return std::construct_at(NEO_ADDRESSOF(on._29), static_cast(args)...); + if constexpr (N == 30) return std::construct_at(NEO_ADDRESSOF(on._30), static_cast(args)...); + if constexpr (N == 31) return std::construct_at(NEO_ADDRESSOF(on._31), static_cast(args)...); + if constexpr (N == 32) return std::construct_at(NEO_ADDRESSOF(on._32), static_cast(args)...); + if constexpr (N == 33) return std::construct_at(NEO_ADDRESSOF(on._33), static_cast(args)...); + if constexpr (N == 34) return std::construct_at(NEO_ADDRESSOF(on._34), static_cast(args)...); + if constexpr (N == 35) return std::construct_at(NEO_ADDRESSOF(on._35), static_cast(args)...); + if constexpr (N == 36) return std::construct_at(NEO_ADDRESSOF(on._36), static_cast(args)...); + if constexpr (N == 37) return std::construct_at(NEO_ADDRESSOF(on._37), static_cast(args)...); + if constexpr (N == 38) return std::construct_at(NEO_ADDRESSOF(on._38), static_cast(args)...); + if constexpr (N == 39) return std::construct_at(NEO_ADDRESSOF(on._39), static_cast(args)...); + if constexpr (N == 40) return std::construct_at(NEO_ADDRESSOF(on._40), static_cast(args)...); + if constexpr (N == 41) return std::construct_at(NEO_ADDRESSOF(on._41), static_cast(args)...); + if constexpr (N == 42) return std::construct_at(NEO_ADDRESSOF(on._42), static_cast(args)...); + if constexpr (N == 43) return std::construct_at(NEO_ADDRESSOF(on._43), static_cast(args)...); + if constexpr (N == 44) return std::construct_at(NEO_ADDRESSOF(on._44), static_cast(args)...); + if constexpr (N == 45) return std::construct_at(NEO_ADDRESSOF(on._45), static_cast(args)...); + if constexpr (N == 46) return std::construct_at(NEO_ADDRESSOF(on._46), static_cast(args)...); + if constexpr (N == 47) return std::construct_at(NEO_ADDRESSOF(on._47), static_cast(args)...); + if constexpr (N == 48) return std::construct_at(NEO_ADDRESSOF(on._48), static_cast(args)...); + if constexpr (N == 49) return std::construct_at(NEO_ADDRESSOF(on._49), static_cast(args)...); + if constexpr (N == 50) return std::construct_at(NEO_ADDRESSOF(on._50), static_cast(args)...); + if constexpr (N == 51) return std::construct_at(NEO_ADDRESSOF(on._51), static_cast(args)...); + if constexpr (N == 52) return std::construct_at(NEO_ADDRESSOF(on._52), static_cast(args)...); + if constexpr (N == 53) return std::construct_at(NEO_ADDRESSOF(on._53), static_cast(args)...); + if constexpr (N == 54) return std::construct_at(NEO_ADDRESSOF(on._54), static_cast(args)...); + if constexpr (N == 55) return std::construct_at(NEO_ADDRESSOF(on._55), static_cast(args)...); + if constexpr (N == 56) return std::construct_at(NEO_ADDRESSOF(on._56), static_cast(args)...); + if constexpr (N == 57) return std::construct_at(NEO_ADDRESSOF(on._57), static_cast(args)...); + if constexpr (N == 58) return std::construct_at(NEO_ADDRESSOF(on._58), static_cast(args)...); + if constexpr (N == 59) return std::construct_at(NEO_ADDRESSOF(on._59), static_cast(args)...); + if constexpr (N == 60) return std::construct_at(NEO_ADDRESSOF(on._60), static_cast(args)...); + if constexpr (N == 61) return std::construct_at(NEO_ADDRESSOF(on._61), static_cast(args)...); + if constexpr (N == 62) return std::construct_at(NEO_ADDRESSOF(on._62), static_cast(args)...); + if constexpr (N == 63) return std::construct_at(NEO_ADDRESSOF(on._63), static_cast(args)...); + if constexpr (N == 64) return std::construct_at(NEO_ADDRESSOF(on._64), static_cast(args)...); + if constexpr (N == 65) return std::construct_at(NEO_ADDRESSOF(on._65), static_cast(args)...); + if constexpr (N == 66) return std::construct_at(NEO_ADDRESSOF(on._66), static_cast(args)...); + if constexpr (N == 67) return std::construct_at(NEO_ADDRESSOF(on._67), static_cast(args)...); + if constexpr (N == 68) return std::construct_at(NEO_ADDRESSOF(on._68), static_cast(args)...); + if constexpr (N == 69) return std::construct_at(NEO_ADDRESSOF(on._69), static_cast(args)...); + if constexpr (N == 70) return std::construct_at(NEO_ADDRESSOF(on._70), static_cast(args)...); + if constexpr (N == 71) return std::construct_at(NEO_ADDRESSOF(on._71), static_cast(args)...); + if constexpr (N == 72) return std::construct_at(NEO_ADDRESSOF(on._72), static_cast(args)...); + if constexpr (N == 73) return std::construct_at(NEO_ADDRESSOF(on._73), static_cast(args)...); + if constexpr (N == 74) return std::construct_at(NEO_ADDRESSOF(on._74), static_cast(args)...); + if constexpr (N == 75) return std::construct_at(NEO_ADDRESSOF(on._75), static_cast(args)...); + if constexpr (N == 76) return std::construct_at(NEO_ADDRESSOF(on._76), static_cast(args)...); + if constexpr (N == 77) return std::construct_at(NEO_ADDRESSOF(on._77), static_cast(args)...); + if constexpr (N == 78) return std::construct_at(NEO_ADDRESSOF(on._78), static_cast(args)...); + if constexpr (N == 79) return std::construct_at(NEO_ADDRESSOF(on._79), static_cast(args)...); + if constexpr (N == 80) return std::construct_at(NEO_ADDRESSOF(on._80), static_cast(args)...); + if constexpr (N == 81) return std::construct_at(NEO_ADDRESSOF(on._81), static_cast(args)...); + if constexpr (N == 82) return std::construct_at(NEO_ADDRESSOF(on._82), static_cast(args)...); + if constexpr (N == 83) return std::construct_at(NEO_ADDRESSOF(on._83), static_cast(args)...); + if constexpr (N == 84) return std::construct_at(NEO_ADDRESSOF(on._84), static_cast(args)...); + if constexpr (N == 85) return std::construct_at(NEO_ADDRESSOF(on._85), static_cast(args)...); + if constexpr (N == 86) return std::construct_at(NEO_ADDRESSOF(on._86), static_cast(args)...); + if constexpr (N == 87) return std::construct_at(NEO_ADDRESSOF(on._87), static_cast(args)...); + if constexpr (N == 88) return std::construct_at(NEO_ADDRESSOF(on._88), static_cast(args)...); + if constexpr (N == 89) return std::construct_at(NEO_ADDRESSOF(on._89), static_cast(args)...); + if constexpr (N == 90) return std::construct_at(NEO_ADDRESSOF(on._90), static_cast(args)...); + if constexpr (N == 91) return std::construct_at(NEO_ADDRESSOF(on._91), static_cast(args)...); + if constexpr (N == 92) return std::construct_at(NEO_ADDRESSOF(on._92), static_cast(args)...); + if constexpr (N == 93) return std::construct_at(NEO_ADDRESSOF(on._93), static_cast(args)...); + if constexpr (N == 94) return std::construct_at(NEO_ADDRESSOF(on._94), static_cast(args)...); + if constexpr (N == 95) return std::construct_at(NEO_ADDRESSOF(on._95), static_cast(args)...); + if constexpr (N == 96) return std::construct_at(NEO_ADDRESSOF(on._96), static_cast(args)...); + if constexpr (N == 97) return std::construct_at(NEO_ADDRESSOF(on._97), static_cast(args)...); + if constexpr (N == 98) return std::construct_at(NEO_ADDRESSOF(on._98), static_cast(args)...); + if constexpr (N == 99) return std::construct_at(NEO_ADDRESSOF(on._99), static_cast(args)...); +} + +template +NEO_ALWAYS_INLINE constexpr void destroy_member(Onion& on) { + if constexpr (N == 0) return std::destroy_at(NEO_ADDRESSOF(on._0)); + if constexpr (N == 1) return std::destroy_at(NEO_ADDRESSOF(on._1)); + if constexpr (N == 2) return std::destroy_at(NEO_ADDRESSOF(on._2)); + if constexpr (N == 3) return std::destroy_at(NEO_ADDRESSOF(on._3)); + if constexpr (N == 4) return std::destroy_at(NEO_ADDRESSOF(on._4)); + if constexpr (N == 5) return std::destroy_at(NEO_ADDRESSOF(on._5)); + if constexpr (N == 6) return std::destroy_at(NEO_ADDRESSOF(on._6)); + if constexpr (N == 7) return std::destroy_at(NEO_ADDRESSOF(on._7)); + if constexpr (N == 8) return std::destroy_at(NEO_ADDRESSOF(on._8)); + if constexpr (N == 9) return std::destroy_at(NEO_ADDRESSOF(on._9)); + if constexpr (N == 10) return std::destroy_at(NEO_ADDRESSOF(on._10)); + if constexpr (N == 11) return std::destroy_at(NEO_ADDRESSOF(on._11)); + if constexpr (N == 12) return std::destroy_at(NEO_ADDRESSOF(on._12)); + if constexpr (N == 13) return std::destroy_at(NEO_ADDRESSOF(on._13)); + if constexpr (N == 14) return std::destroy_at(NEO_ADDRESSOF(on._14)); + if constexpr (N == 15) return std::destroy_at(NEO_ADDRESSOF(on._15)); + if constexpr (N == 16) return std::destroy_at(NEO_ADDRESSOF(on._16)); + if constexpr (N == 17) return std::destroy_at(NEO_ADDRESSOF(on._17)); + if constexpr (N == 18) return std::destroy_at(NEO_ADDRESSOF(on._18)); + if constexpr (N == 19) return std::destroy_at(NEO_ADDRESSOF(on._19)); + if constexpr (N == 20) return std::destroy_at(NEO_ADDRESSOF(on._20)); + if constexpr (N == 21) return std::destroy_at(NEO_ADDRESSOF(on._21)); + if constexpr (N == 22) return std::destroy_at(NEO_ADDRESSOF(on._22)); + if constexpr (N == 23) return std::destroy_at(NEO_ADDRESSOF(on._23)); + if constexpr (N == 24) return std::destroy_at(NEO_ADDRESSOF(on._24)); + if constexpr (N == 25) return std::destroy_at(NEO_ADDRESSOF(on._25)); + if constexpr (N == 26) return std::destroy_at(NEO_ADDRESSOF(on._26)); + if constexpr (N == 27) return std::destroy_at(NEO_ADDRESSOF(on._27)); + if constexpr (N == 28) return std::destroy_at(NEO_ADDRESSOF(on._28)); + if constexpr (N == 29) return std::destroy_at(NEO_ADDRESSOF(on._29)); + if constexpr (N == 30) return std::destroy_at(NEO_ADDRESSOF(on._30)); + if constexpr (N == 31) return std::destroy_at(NEO_ADDRESSOF(on._31)); + if constexpr (N == 32) return std::destroy_at(NEO_ADDRESSOF(on._32)); + if constexpr (N == 33) return std::destroy_at(NEO_ADDRESSOF(on._33)); + if constexpr (N == 34) return std::destroy_at(NEO_ADDRESSOF(on._34)); + if constexpr (N == 35) return std::destroy_at(NEO_ADDRESSOF(on._35)); + if constexpr (N == 36) return std::destroy_at(NEO_ADDRESSOF(on._36)); + if constexpr (N == 37) return std::destroy_at(NEO_ADDRESSOF(on._37)); + if constexpr (N == 38) return std::destroy_at(NEO_ADDRESSOF(on._38)); + if constexpr (N == 39) return std::destroy_at(NEO_ADDRESSOF(on._39)); + if constexpr (N == 40) return std::destroy_at(NEO_ADDRESSOF(on._40)); + if constexpr (N == 41) return std::destroy_at(NEO_ADDRESSOF(on._41)); + if constexpr (N == 42) return std::destroy_at(NEO_ADDRESSOF(on._42)); + if constexpr (N == 43) return std::destroy_at(NEO_ADDRESSOF(on._43)); + if constexpr (N == 44) return std::destroy_at(NEO_ADDRESSOF(on._44)); + if constexpr (N == 45) return std::destroy_at(NEO_ADDRESSOF(on._45)); + if constexpr (N == 46) return std::destroy_at(NEO_ADDRESSOF(on._46)); + if constexpr (N == 47) return std::destroy_at(NEO_ADDRESSOF(on._47)); + if constexpr (N == 48) return std::destroy_at(NEO_ADDRESSOF(on._48)); + if constexpr (N == 49) return std::destroy_at(NEO_ADDRESSOF(on._49)); + if constexpr (N == 50) return std::destroy_at(NEO_ADDRESSOF(on._50)); + if constexpr (N == 51) return std::destroy_at(NEO_ADDRESSOF(on._51)); + if constexpr (N == 52) return std::destroy_at(NEO_ADDRESSOF(on._52)); + if constexpr (N == 53) return std::destroy_at(NEO_ADDRESSOF(on._53)); + if constexpr (N == 54) return std::destroy_at(NEO_ADDRESSOF(on._54)); + if constexpr (N == 55) return std::destroy_at(NEO_ADDRESSOF(on._55)); + if constexpr (N == 56) return std::destroy_at(NEO_ADDRESSOF(on._56)); + if constexpr (N == 57) return std::destroy_at(NEO_ADDRESSOF(on._57)); + if constexpr (N == 58) return std::destroy_at(NEO_ADDRESSOF(on._58)); + if constexpr (N == 59) return std::destroy_at(NEO_ADDRESSOF(on._59)); + if constexpr (N == 60) return std::destroy_at(NEO_ADDRESSOF(on._60)); + if constexpr (N == 61) return std::destroy_at(NEO_ADDRESSOF(on._61)); + if constexpr (N == 62) return std::destroy_at(NEO_ADDRESSOF(on._62)); + if constexpr (N == 63) return std::destroy_at(NEO_ADDRESSOF(on._63)); + if constexpr (N == 64) return std::destroy_at(NEO_ADDRESSOF(on._64)); + if constexpr (N == 65) return std::destroy_at(NEO_ADDRESSOF(on._65)); + if constexpr (N == 66) return std::destroy_at(NEO_ADDRESSOF(on._66)); + if constexpr (N == 67) return std::destroy_at(NEO_ADDRESSOF(on._67)); + if constexpr (N == 68) return std::destroy_at(NEO_ADDRESSOF(on._68)); + if constexpr (N == 69) return std::destroy_at(NEO_ADDRESSOF(on._69)); + if constexpr (N == 70) return std::destroy_at(NEO_ADDRESSOF(on._70)); + if constexpr (N == 71) return std::destroy_at(NEO_ADDRESSOF(on._71)); + if constexpr (N == 72) return std::destroy_at(NEO_ADDRESSOF(on._72)); + if constexpr (N == 73) return std::destroy_at(NEO_ADDRESSOF(on._73)); + if constexpr (N == 74) return std::destroy_at(NEO_ADDRESSOF(on._74)); + if constexpr (N == 75) return std::destroy_at(NEO_ADDRESSOF(on._75)); + if constexpr (N == 76) return std::destroy_at(NEO_ADDRESSOF(on._76)); + if constexpr (N == 77) return std::destroy_at(NEO_ADDRESSOF(on._77)); + if constexpr (N == 78) return std::destroy_at(NEO_ADDRESSOF(on._78)); + if constexpr (N == 79) return std::destroy_at(NEO_ADDRESSOF(on._79)); + if constexpr (N == 80) return std::destroy_at(NEO_ADDRESSOF(on._80)); + if constexpr (N == 81) return std::destroy_at(NEO_ADDRESSOF(on._81)); + if constexpr (N == 82) return std::destroy_at(NEO_ADDRESSOF(on._82)); + if constexpr (N == 83) return std::destroy_at(NEO_ADDRESSOF(on._83)); + if constexpr (N == 84) return std::destroy_at(NEO_ADDRESSOF(on._84)); + if constexpr (N == 85) return std::destroy_at(NEO_ADDRESSOF(on._85)); + if constexpr (N == 86) return std::destroy_at(NEO_ADDRESSOF(on._86)); + if constexpr (N == 87) return std::destroy_at(NEO_ADDRESSOF(on._87)); + if constexpr (N == 88) return std::destroy_at(NEO_ADDRESSOF(on._88)); + if constexpr (N == 89) return std::destroy_at(NEO_ADDRESSOF(on._89)); + if constexpr (N == 90) return std::destroy_at(NEO_ADDRESSOF(on._90)); + if constexpr (N == 91) return std::destroy_at(NEO_ADDRESSOF(on._91)); + if constexpr (N == 92) return std::destroy_at(NEO_ADDRESSOF(on._92)); + if constexpr (N == 93) return std::destroy_at(NEO_ADDRESSOF(on._93)); + if constexpr (N == 94) return std::destroy_at(NEO_ADDRESSOF(on._94)); + if constexpr (N == 95) return std::destroy_at(NEO_ADDRESSOF(on._95)); + if constexpr (N == 96) return std::destroy_at(NEO_ADDRESSOF(on._96)); + if constexpr (N == 97) return std::destroy_at(NEO_ADDRESSOF(on._97)); + if constexpr (N == 98) return std::destroy_at(NEO_ADDRESSOF(on._98)); + if constexpr (N == 99) return std::destroy_at(NEO_ADDRESSOF(on._99)); +} + +} + +template <> +union constexpr_union<> { + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_NO_UNIQUE_ADDRESS unit nil; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + else if constexpr (N == 46) + return (_46); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + else if constexpr (N == 46) + return (_46); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + else if constexpr (N == 46) + return (_46); + else if constexpr (N == 47) + return (_47); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + else if constexpr (N == 46) + return (_46); + else if constexpr (N == 47) + return (_47); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + else if constexpr (N == 46) + return (_46); + else if constexpr (N == 47) + return (_47); + else if constexpr (N == 48) + return (_48); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + else if constexpr (N == 46) + return (_46); + else if constexpr (N == 47) + return (_47); + else if constexpr (N == 48) + return (_48); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + else if constexpr (N == 46) + return (_46); + else if constexpr (N == 47) + return (_47); + else if constexpr (N == 48) + return (_48); + else if constexpr (N == 49) + return (_49); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + if constexpr (false) {} + else if constexpr (N == 0) + return (_0); + else if constexpr (N == 1) + return (_1); + else if constexpr (N == 2) + return (_2); + else if constexpr (N == 3) + return (_3); + else if constexpr (N == 4) + return (_4); + else if constexpr (N == 5) + return (_5); + else if constexpr (N == 6) + return (_6); + else if constexpr (N == 7) + return (_7); + else if constexpr (N == 8) + return (_8); + else if constexpr (N == 9) + return (_9); + else if constexpr (N == 10) + return (_10); + else if constexpr (N == 11) + return (_11); + else if constexpr (N == 12) + return (_12); + else if constexpr (N == 13) + return (_13); + else if constexpr (N == 14) + return (_14); + else if constexpr (N == 15) + return (_15); + else if constexpr (N == 16) + return (_16); + else if constexpr (N == 17) + return (_17); + else if constexpr (N == 18) + return (_18); + else if constexpr (N == 19) + return (_19); + else if constexpr (N == 20) + return (_20); + else if constexpr (N == 21) + return (_21); + else if constexpr (N == 22) + return (_22); + else if constexpr (N == 23) + return (_23); + else if constexpr (N == 24) + return (_24); + else if constexpr (N == 25) + return (_25); + else if constexpr (N == 26) + return (_26); + else if constexpr (N == 27) + return (_27); + else if constexpr (N == 28) + return (_28); + else if constexpr (N == 29) + return (_29); + else if constexpr (N == 30) + return (_30); + else if constexpr (N == 31) + return (_31); + else if constexpr (N == 32) + return (_32); + else if constexpr (N == 33) + return (_33); + else if constexpr (N == 34) + return (_34); + else if constexpr (N == 35) + return (_35); + else if constexpr (N == 36) + return (_36); + else if constexpr (N == 37) + return (_37); + else if constexpr (N == 38) + return (_38); + else if constexpr (N == 39) + return (_39); + else if constexpr (N == 40) + return (_40); + else if constexpr (N == 41) + return (_41); + else if constexpr (N == 42) + return (_42); + else if constexpr (N == 43) + return (_43); + else if constexpr (N == 44) + return (_44); + else if constexpr (N == 45) + return (_45); + else if constexpr (N == 46) + return (_46); + else if constexpr (N == 47) + return (_47); + else if constexpr (N == 48) + return (_48); + else if constexpr (N == 49) + return (_49); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; + NEO_NO_UNIQUE_ADDRESS T91 _91; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; + NEO_NO_UNIQUE_ADDRESS T91 _91; + NEO_NO_UNIQUE_ADDRESS T92 _92; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; + NEO_NO_UNIQUE_ADDRESS T91 _91; + NEO_NO_UNIQUE_ADDRESS T92 _92; + NEO_NO_UNIQUE_ADDRESS T93 _93; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; + NEO_NO_UNIQUE_ADDRESS T91 _91; + NEO_NO_UNIQUE_ADDRESS T92 _92; + NEO_NO_UNIQUE_ADDRESS T93 _93; + NEO_NO_UNIQUE_ADDRESS T94 _94; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; + NEO_NO_UNIQUE_ADDRESS T91 _91; + NEO_NO_UNIQUE_ADDRESS T92 _92; + NEO_NO_UNIQUE_ADDRESS T93 _93; + NEO_NO_UNIQUE_ADDRESS T94 _94; + NEO_NO_UNIQUE_ADDRESS T95 _95; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; + NEO_NO_UNIQUE_ADDRESS T91 _91; + NEO_NO_UNIQUE_ADDRESS T92 _92; + NEO_NO_UNIQUE_ADDRESS T93 _93; + NEO_NO_UNIQUE_ADDRESS T94 _94; + NEO_NO_UNIQUE_ADDRESS T95 _95; + NEO_NO_UNIQUE_ADDRESS T96 _96; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; + NEO_NO_UNIQUE_ADDRESS T91 _91; + NEO_NO_UNIQUE_ADDRESS T92 _92; + NEO_NO_UNIQUE_ADDRESS T93 _93; + NEO_NO_UNIQUE_ADDRESS T94 _94; + NEO_NO_UNIQUE_ADDRESS T95 _95; + NEO_NO_UNIQUE_ADDRESS T96 _96; + NEO_NO_UNIQUE_ADDRESS T97 _97; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; + NEO_NO_UNIQUE_ADDRESS T91 _91; + NEO_NO_UNIQUE_ADDRESS T92 _92; + NEO_NO_UNIQUE_ADDRESS T93 _93; + NEO_NO_UNIQUE_ADDRESS T94 _94; + NEO_NO_UNIQUE_ADDRESS T95 _95; + NEO_NO_UNIQUE_ADDRESS T96 _96; + NEO_NO_UNIQUE_ADDRESS T97 _97; + NEO_NO_UNIQUE_ADDRESS T98 _98; +}; + +template +union constexpr_union { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + return detail::get_member&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + return detail::get_member const&>(*this); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + + NEO_NO_UNIQUE_ADDRESS T0 _0; + NEO_NO_UNIQUE_ADDRESS T1 _1; + NEO_NO_UNIQUE_ADDRESS T2 _2; + NEO_NO_UNIQUE_ADDRESS T3 _3; + NEO_NO_UNIQUE_ADDRESS T4 _4; + NEO_NO_UNIQUE_ADDRESS T5 _5; + NEO_NO_UNIQUE_ADDRESS T6 _6; + NEO_NO_UNIQUE_ADDRESS T7 _7; + NEO_NO_UNIQUE_ADDRESS T8 _8; + NEO_NO_UNIQUE_ADDRESS T9 _9; + NEO_NO_UNIQUE_ADDRESS T10 _10; + NEO_NO_UNIQUE_ADDRESS T11 _11; + NEO_NO_UNIQUE_ADDRESS T12 _12; + NEO_NO_UNIQUE_ADDRESS T13 _13; + NEO_NO_UNIQUE_ADDRESS T14 _14; + NEO_NO_UNIQUE_ADDRESS T15 _15; + NEO_NO_UNIQUE_ADDRESS T16 _16; + NEO_NO_UNIQUE_ADDRESS T17 _17; + NEO_NO_UNIQUE_ADDRESS T18 _18; + NEO_NO_UNIQUE_ADDRESS T19 _19; + NEO_NO_UNIQUE_ADDRESS T20 _20; + NEO_NO_UNIQUE_ADDRESS T21 _21; + NEO_NO_UNIQUE_ADDRESS T22 _22; + NEO_NO_UNIQUE_ADDRESS T23 _23; + NEO_NO_UNIQUE_ADDRESS T24 _24; + NEO_NO_UNIQUE_ADDRESS T25 _25; + NEO_NO_UNIQUE_ADDRESS T26 _26; + NEO_NO_UNIQUE_ADDRESS T27 _27; + NEO_NO_UNIQUE_ADDRESS T28 _28; + NEO_NO_UNIQUE_ADDRESS T29 _29; + NEO_NO_UNIQUE_ADDRESS T30 _30; + NEO_NO_UNIQUE_ADDRESS T31 _31; + NEO_NO_UNIQUE_ADDRESS T32 _32; + NEO_NO_UNIQUE_ADDRESS T33 _33; + NEO_NO_UNIQUE_ADDRESS T34 _34; + NEO_NO_UNIQUE_ADDRESS T35 _35; + NEO_NO_UNIQUE_ADDRESS T36 _36; + NEO_NO_UNIQUE_ADDRESS T37 _37; + NEO_NO_UNIQUE_ADDRESS T38 _38; + NEO_NO_UNIQUE_ADDRESS T39 _39; + NEO_NO_UNIQUE_ADDRESS T40 _40; + NEO_NO_UNIQUE_ADDRESS T41 _41; + NEO_NO_UNIQUE_ADDRESS T42 _42; + NEO_NO_UNIQUE_ADDRESS T43 _43; + NEO_NO_UNIQUE_ADDRESS T44 _44; + NEO_NO_UNIQUE_ADDRESS T45 _45; + NEO_NO_UNIQUE_ADDRESS T46 _46; + NEO_NO_UNIQUE_ADDRESS T47 _47; + NEO_NO_UNIQUE_ADDRESS T48 _48; + NEO_NO_UNIQUE_ADDRESS T49 _49; + NEO_NO_UNIQUE_ADDRESS T50 _50; + NEO_NO_UNIQUE_ADDRESS T51 _51; + NEO_NO_UNIQUE_ADDRESS T52 _52; + NEO_NO_UNIQUE_ADDRESS T53 _53; + NEO_NO_UNIQUE_ADDRESS T54 _54; + NEO_NO_UNIQUE_ADDRESS T55 _55; + NEO_NO_UNIQUE_ADDRESS T56 _56; + NEO_NO_UNIQUE_ADDRESS T57 _57; + NEO_NO_UNIQUE_ADDRESS T58 _58; + NEO_NO_UNIQUE_ADDRESS T59 _59; + NEO_NO_UNIQUE_ADDRESS T60 _60; + NEO_NO_UNIQUE_ADDRESS T61 _61; + NEO_NO_UNIQUE_ADDRESS T62 _62; + NEO_NO_UNIQUE_ADDRESS T63 _63; + NEO_NO_UNIQUE_ADDRESS T64 _64; + NEO_NO_UNIQUE_ADDRESS T65 _65; + NEO_NO_UNIQUE_ADDRESS T66 _66; + NEO_NO_UNIQUE_ADDRESS T67 _67; + NEO_NO_UNIQUE_ADDRESS T68 _68; + NEO_NO_UNIQUE_ADDRESS T69 _69; + NEO_NO_UNIQUE_ADDRESS T70 _70; + NEO_NO_UNIQUE_ADDRESS T71 _71; + NEO_NO_UNIQUE_ADDRESS T72 _72; + NEO_NO_UNIQUE_ADDRESS T73 _73; + NEO_NO_UNIQUE_ADDRESS T74 _74; + NEO_NO_UNIQUE_ADDRESS T75 _75; + NEO_NO_UNIQUE_ADDRESS T76 _76; + NEO_NO_UNIQUE_ADDRESS T77 _77; + NEO_NO_UNIQUE_ADDRESS T78 _78; + NEO_NO_UNIQUE_ADDRESS T79 _79; + NEO_NO_UNIQUE_ADDRESS T80 _80; + NEO_NO_UNIQUE_ADDRESS T81 _81; + NEO_NO_UNIQUE_ADDRESS T82 _82; + NEO_NO_UNIQUE_ADDRESS T83 _83; + NEO_NO_UNIQUE_ADDRESS T84 _84; + NEO_NO_UNIQUE_ADDRESS T85 _85; + NEO_NO_UNIQUE_ADDRESS T86 _86; + NEO_NO_UNIQUE_ADDRESS T87 _87; + NEO_NO_UNIQUE_ADDRESS T88 _88; + NEO_NO_UNIQUE_ADDRESS T89 _89; + NEO_NO_UNIQUE_ADDRESS T90 _90; + NEO_NO_UNIQUE_ADDRESS T91 _91; + NEO_NO_UNIQUE_ADDRESS T92 _92; + NEO_NO_UNIQUE_ADDRESS T93 _93; + NEO_NO_UNIQUE_ADDRESS T94 _94; + NEO_NO_UNIQUE_ADDRESS T95 _95; + NEO_NO_UNIQUE_ADDRESS T96 _96; + NEO_NO_UNIQUE_ADDRESS T97 _97; + NEO_NO_UNIQUE_ADDRESS T98 _98; + NEO_NO_UNIQUE_ADDRESS T99 _99; +}; + +#if 0 +// In principal, arbitrarily many types could be supported, but some compilers consider it UB to +// access the tail sub-union if the head sub-union has an active member. GCC accepts, but Clang +// rejects. This might not have a pretty solution. + +// Specialization for at least ten types, which subdivides the arguments into +// smaller sub-unions. +template + requires(sizeof...(More) != 0) +union constexpr_union { + using FirstNext = constexpr_union; + using Tail = constexpr_union; + + constexpr constexpr_union(constexpr_union&&) = default; + constexpr constexpr_union(constexpr_union const&) = default; + constexpr constexpr_union& operator=(constexpr_union&&) = default; + constexpr constexpr_union& operator=(constexpr_union const&) = default; + + constexpr constexpr_union() noexcept + : _first_ten() {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires(not neo_is_trivially_destructible(FirstNext) + or not neo_is_trivially_destructible(Tail)) + {} + + template + using nth_type = meta::at; + + template + constexpr nth_type& get() & noexcept { + if constexpr (N < 10) { + return _first_ten.template get(); + } else { + return _tail.template get(); + } + } + + template + constexpr nth_type const& get() const& noexcept { + if constexpr (N < 10) { + return _first_ten.template get(); + } else { + return _tail.template get(); + } + } + + template + constexpr nth_type&& get() && noexcept { + if constexpr (N < 10) { + return _first_ten.template get(); + } else { + return _tail.template get(); + } + } + + template + constexpr nth_type const&& get() const&& noexcept { + if constexpr (N < 10) { + return _first_ten.template get(); + } else { + return _tail.template get(); + } + } + + template + constexpr nth_type& + construct(Args&&... args) noexcept(noexcept(nth_type(static_cast(args)...))) { + if constexpr (N < 10) { + return _first_ten.template construct(static_cast(args)...); + } else { + return _tail.template construct(static_cast(args)...); + } + } + + template + requires requires { typename nth_type; } + constexpr void destroy() noexcept { + if constexpr (N < 10) { + _first_ten.template destroy(); + } else { + _tail.template destroy(); + } + } + + NEO_NO_UNIQUE_ADDRESS FirstNext _first_ten; + NEO_NO_UNIQUE_ADDRESS Tail _tail; +}; + +#endif // disabled + +} // namespace neo diff --git a/src/neo/constexpr_union.hpp.jinja b/src/neo/constexpr_union.hpp.jinja new file mode 100644 index 0000000..2019b00 --- /dev/null +++ b/src/neo/constexpr_union.hpp.jinja @@ -0,0 +1,276 @@ +#pragma once + +// clang-format off + +{{generated_file_notice('src/neo/constexpr_union.hpp.jinja')}} +{#- + To render this template, run render.py (at the root of this repo), feeding + this file to the script's stdin +#} + +#include +#include +#include +#include +#include +#include + +#include // std::construct_at + +namespace neo { + +/** + * @brief A variadic union template that is default-constructible and `constexpr`-ready. + * + * Defines three member function templates: + * + * - `get() -> nth_type [const] [&|&&]` obtain a reference to the `Nth` union member. + * - `construct(auto&&...) -> nth_type&` activate the `Nth` union member by calling + * the constructor with the given arguments. No other union members are modified. + * - `destroy() -> void` - Destroy the `Nth` union member by calling its destructor. + * + * Every specialization of `constexpr_union` constains a `nil` alternative which is + * activated upon default-construction of the union. The names of the variadic members are + * the zero-based index of the member with an underscore prefix (e.g. `_0`, `_1`, `_2`, `_3`). + * To access the `Nth` member generically, use the `get()` member function template, which + * returns a reference to that member with the cvref-qualifiers of the instance used to call the + * `get` member. To get the `Nth` type of the union, use the `nth_type` member alias + * template. + * + * The union is not a "`variant`"": it is up to the user to track the active member and + * to correctly call the constructors/destructors when needed. The sole purpose of + * this class template is to simplify the implementation of `variant`/`optional`-style + * class templates. + * + * Because of the implicit `nil` member, a `constexpr_union` can be used as storage + * for an optional `T`, with the `nil` member acting as a the "null" state. + * + * All union members are marked with `[[no_uninque_address]]`. + * + * @tparam Ts... The alternative of the union. Must not be empty. + */ +template +union constexpr_union; + +namespace detail { + +template +concept all_trivially_destructible = + (neo_is_trivially_destructible(Ts) and ... and true); + +template +NEO_ALWAYS_INLINE constexpr Ret get_member(Onion&& on) noexcept { + {%- for n in range(100) %} + if constexpr (N == {{n}}) return static_cast(on._{{n}}); + {%- endfor %} +} + +template +NEO_ALWAYS_INLINE constexpr auto construct_member(Onion& on, Args&&... args) { + {%- for n in range(100) %} + if constexpr (N == {{n}}) return std::construct_at(NEO_ADDRESSOF(on._{{n}}), static_cast(args)...); + {%- endfor %} +} + +template +NEO_ALWAYS_INLINE constexpr void destroy_member(Onion& on) { + {%- for n in range(100) %} + if constexpr (N == {{n}}) return std::destroy_at(NEO_ADDRESSOF(on._{{n}})); + {%- endfor %} +} + +} + +template <> +union constexpr_union<> { + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_NO_UNIQUE_ADDRESS unit nil; +}; + +#% for n in range(1, 100+1) +template <{{range(n) | format_each('typename T{}') | join(', ')}}> +union constexpr_union<{{range(n) | format_each('T{}') | join(', ')}}> { + template + using nth_type = meta::pack_at; + + NEO_ALWAYS_INLINE constexpr constexpr_union() noexcept + : nil() + {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires (not detail::all_trivially_destructible<{{range(n) | format_each('T{}') | join(', ')}}>) + {} + + template + NEO_ALWAYS_INLINE constexpr nth_type& construct(Args&&... args) + noexcept(noexcept(nth_type(static_cast(args)...))) + { + return *detail::construct_member(*this, static_cast(args)...); + } + + template > + NEO_ALWAYS_INLINE constexpr void destroy() noexcept { + detail::destroy_member(*this); + } + + {%- macro foreach_member() -%} + {% for nth in range(n) -%} + {{caller(nth, 'T{}'.format(nth), '_{}'.format(nth))}} + {%- endfor %} + {%- endmacro %} + + {%- macro getters(cast, T) -%} + {%- if n > 50 -%} + return detail::get_member(*this); + {%- else -%} + if constexpr (false) {} + {%- call(idx, _type, member) foreach_member() %} + else if constexpr (N == {{idx}}) + return {{cast}}({{member}}); + {%- endcall -%} + {%- endif %} + {%- endmacro %} + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type& get() & noexcept { + {{ getters('', 'nth_type&') }} + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const& get() const & noexcept { + {{ getters('', 'nth_type const&') }} + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type&& get() && noexcept { + return NEO_MOVE(this->get()); + } + + template + [[nodiscard]] NEO_ALWAYS_INLINE constexpr nth_type const&& get() const && noexcept { + return NEO_MOVE(this->get()); + } + + NEO_NO_UNIQUE_ADDRESS unit nil; + + constexpr_union(constexpr_union&&) = default; + constexpr_union(constexpr_union const&) = default; + constexpr_union& operator=(constexpr_union&&) = default; + constexpr_union& operator=(constexpr_union const&) = default; + {# . #} + + {%- call(_, type, name) foreach_member() %} + NEO_NO_UNIQUE_ADDRESS {{type}} {{name}}; + {%- endcall %} +}; +{##} +#% endfor + +#if 0 +// In principal, arbitrarily many types could be supported, but some compilers consider it UB to +// access the tail sub-union if the head sub-union has an active member. GCC accepts, but Clang +// rejects. This might not have a pretty solution. + +// Specialization for at least ten types, which subdivides the arguments into +// smaller sub-unions. +template + requires(sizeof...(More) != 0) +union constexpr_union { + using FirstNext = constexpr_union; + using Tail = constexpr_union; + + constexpr constexpr_union(constexpr_union&&) = default; + constexpr constexpr_union(constexpr_union const&) = default; + constexpr constexpr_union& operator=(constexpr_union&&) = default; + constexpr constexpr_union& operator=(constexpr_union const&) = default; + + constexpr constexpr_union() noexcept + : _first_ten() {} + + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() = default; + NEO_CONSTEXPR_DESTRUCTOR ~constexpr_union() + requires(not neo_is_trivially_destructible(FirstNext) + or not neo_is_trivially_destructible(Tail)) + {} + + template + using nth_type = meta::at; + + template + constexpr nth_type& get() & noexcept { + if constexpr (N < 10) { + return _first_ten.template get(); + } else { + return _tail.template get(); + } + } + + template + constexpr nth_type const& get() const& noexcept { + if constexpr (N < 10) { + return _first_ten.template get(); + } else { + return _tail.template get(); + } + } + + template + constexpr nth_type&& get() && noexcept { + if constexpr (N < 10) { + return _first_ten.template get(); + } else { + return _tail.template get(); + } + } + + template + constexpr nth_type const&& get() const&& noexcept { + if constexpr (N < 10) { + return _first_ten.template get(); + } else { + return _tail.template get(); + } + } + + template + constexpr nth_type& + construct(Args&&... args) noexcept(noexcept(nth_type(static_cast(args)...))) { + if constexpr (N < 10) { + return _first_ten.template construct(static_cast(args)...); + } else { + return _tail.template construct(static_cast(args)...); + } + } + + template + requires requires { typename nth_type; } + constexpr void destroy() noexcept { + if constexpr (N < 10) { + _first_ten.template destroy(); + } else { + _tail.template destroy(); + } + } + + NEO_NO_UNIQUE_ADDRESS FirstNext _first_ten; + NEO_NO_UNIQUE_ADDRESS Tail _tail; +}; + +#endif // disabled + +} // namespace neo + diff --git a/src/neo/constexpr_union.test.cpp b/src/neo/constexpr_union.test.cpp new file mode 100644 index 0000000..8226268 --- /dev/null +++ b/src/neo/constexpr_union.test.cpp @@ -0,0 +1,68 @@ +#include + +#include +#include + +#include + +template +constexpr auto make_union(Args&&... args) { + using onion_type = neo::constexpr_union; + onion_type onion; + std::construct_at(&onion.template get(), args...); + onion.template construct(args...); + using T = typename onion_type::template nth_type; + auto dup = onion.template get(); + onion.template get().~T(); + return dup; +} + +TEST_CASE("Create a simple union") { + neo::constexpr_union a; + a.get<0>() = 31; + CHECK(a.get<0>() == 31); + + auto q = make_union<1, double, int, int>(31); + CHECK(q == 31); + + constexpr auto Q = make_union<1, double, int, int>(31); + STATIC_REQUIRE(Q == 31); +} + +TEST_CASE("Large") { + // clang-format off + constexpr auto x = make_union<31, int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int>(42); + // clang-format on + STATIC_REQUIRE(x == 42); +} + +struct nontrivial { + constexpr nontrivial() {} + constexpr ~nontrivial() {} + int value = 31; +}; + +TEST_CASE("Non-trivial") { + neo::constexpr_union a; + a.get<1>() = 31; + CHECK(a.get<1>() == 31); + std::construct_at(&a.get<0>(), "hey"); + CHECK(a.get<0>() == "hey"); + + { + constexpr auto n = make_union<1, int, nontrivial, std::string>(); + STATIC_REQUIRE(n.value == 31); + } +} + +neo::testing::cx_test_case ChangingActiveMember = [](auto) consteval { + neo::constexpr_union onion; + onion.construct<1>(); // Should be constexpr-okay +}; diff --git a/src/neo/declval.hpp b/src/neo/declval.hpp index 36d80ee..d383d81 100644 --- a/src/neo/declval.hpp +++ b/src/neo/declval.hpp @@ -1,13 +1,22 @@ #pragma once +#include + namespace neo { +#if NEO_HAS_BUILTIN(__add_rvalue_reference) +template +using add_rref_t = __add_rvalue_reference(T); +#define _neoDeclVal(...) (((__add_rvalue_reference(__VA_ARGS__)(*)())(void*)(nullptr))()) +#else template using add_rref_t = T&&; +#define _neoDeclVal(...) (((::neo::add_rref_t<__VA_ARGS__>(*)())(void*)(nullptr))()) +#endif } // namespace neo /** * @brief Equivalent of std::declval(), but less compiler overhead */ -#define NEO_DECLVAL(...) (((::neo::add_rref_t<__VA_ARGS__>(*)())(void*)(nullptr))()) +#define NEO_DECLVAL(...) _neoDeclVal(__VA_ARGS__) diff --git a/src/neo/emplacement.hpp b/src/neo/emplacement.hpp index e95462b..85c942d 100644 --- a/src/neo/emplacement.hpp +++ b/src/neo/emplacement.hpp @@ -3,29 +3,24 @@ #include "./fwd.hpp" #include -#include namespace neo { template requires requires(void* p, Args&&... args) { ::new (p) T(NEO_FWD(args)...); } -constexpr auto construct_at(T* addr, - Args&&... args) // +[[deprecated("Use std::construct_at")]] constexpr auto construct_at(T* addr, + Args&&... args) // noexcept(noexcept(::new((void*)0) T(NEO_FWD(args)...))) { return std::construct_at(addr, NEO_FWD(args)...); } template -constexpr void destroy_at(T* addr) { - addr->~T(); +[[deprecated("Use std::destroy_at")]] constexpr void destroy_at(T* addr) { + std::destroy_at(addr); } -#if defined __GNUC__ || defined _MSC_VER -// GCC, Clang, and MSVC all support constexpr placement-new, so we'll just expand a macro for it -#define NEO_CONSTRUCT_AT(Address, ...) (::std::construct_at(Address __VA_OPT__(, ) __VA_ARGS__)) -#else #define NEO_CONSTRUCT_AT ::neo::construct_at -#endif + // No compiler lets this "just work" #define NEO_DESTROY_AT (::neo::destroy_at) diff --git a/src/neo/fwd.hpp b/src/neo/fwd.hpp index 900cc0b..526d5d6 100644 --- a/src/neo/fwd.hpp +++ b/src/neo/fwd.hpp @@ -1,5 +1,7 @@ #pragma once +#include + namespace neo::move_detail { template @@ -17,8 +19,8 @@ struct strip_type { using type = T; }; -#ifdef __GNUC__ -#define _neo_typeof_noref(...) __typeof__((__VA_ARGS__)) +#if NEO_HAS_BUILTIN(__remove_reference) +#define _neo_typeof_noref(...) __remove_reference(decltype(__VA_ARGS__)) #else #define _neo_typeof_noref(...) typename ::neo::move_detail::strip_type::type #endif diff --git a/src/neo/get.detail.hpp b/src/neo/get.detail.hpp new file mode 100644 index 0000000..4ace374 --- /dev/null +++ b/src/neo/get.detail.hpp @@ -0,0 +1,277 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace neo::_get { + +// Match an opt-ref like type of unspecified referred-to type +template +concept opt_ref_like = requires(const Ref const_ref, Ref mut_ref) { + { const_ref ? 0 : 0 } noexcept; + { *const_ref }; + { *const_ref } -> neo::weak_same_as; + requires semiregular; +}; + +// Match an opt-ref-like whose dereference operator returns the given type +template +concept opt_ref_to = opt_ref_like and requires(const OptRef ref) { + { *ref } -> neo::weak_same_as; +}; + +// Some standard library types are not sfinae-friendly, but we want to make a SFINAE-friendly get<> +// Use some variable templates to force the issue. In the base case, the mask is always `true` +// since we can rely on other methods of exclusing non-stdlib types. +template +constexpr bool sfinae_mask = true; + +template +constexpr bool sfinae_mask_n = true; + +template +constexpr bool sfinae_mask, Alt> = (weak_same_as || ...); + +template +constexpr bool sfinae_mask, Alt> = (weak_same_as || ...); + +template +constexpr bool sfinae_mask_n, N> = sizeof...(Ts) > N; + +template +constexpr bool sfinae_mask_n, N> = sizeof...(Ts) > N; + +template +constexpr bool sfinae_mask_n, N> = N < Len; + +template +constexpr bool sfinae_mask_n, N> = N < 2; + +template +void try_get() = delete; + +template +void try_get() = delete; + +template +void get() = delete; + +template +void get() = delete; + +namespace declared { +// Does `T` have a `nth_type<>` member alias template? +template +concept has_member_template_nth_type = requires { typename T::template nth_type; }; +// Does `T` have a valid std::tuple_element_t? +template +concept has_std_tuple_element + = sfinae_mask_n and requires { typename std::tuple_element_t; }; +// Does `T` have a valid std::variant_alternative_t? +template +concept has_std_variant_alternative + = sfinae_mask_n and requires { typename std::variant_alternative_t; }; + +template +struct try_var_alt {}; + +template +struct try_tpl_elem { + template + using f = try_var_alt>::template f; +}; + +template +struct try_nth_type { + template + using f = try_tpl_elem>::template f; +}; + +template <> +struct try_nth_type { + template + using f = typename T::template nth_type; +}; + +template <> +struct try_tpl_elem { + template + using f = std::tuple_element_t; +}; + +template <> +struct try_var_alt { + template + using f = std::variant_alternative_t; +}; + +template +using nth = try_nth_type>::template f; +} // namespace declared + +template +using nth_type_t = declared::nth, N>; + +template +concept has_nth_type = requires { typename nth_type_t; }; + +template +using forward_nth_type_t = forward_like_tuple_t>; + +template +concept has_member_try_get_nth = requires(T&& var) { + { var.template try_get() } noexcept -> opt_ref_to>; +}; + +template +concept has_free_try_get_nth = requires(T&& var) { + { try_get(var) } noexcept -> opt_ref_to>; +}; + +template +concept has_free_get_if_nth = requires(T&& var) { + requires sfinae_mask_n, N>; + { get_if(NEO_ADDRESSOF(var)) } noexcept -> opt_ref_to>; +}; + +template +concept has_any_try_get_nth_backend + = has_member_try_get_nth or has_free_try_get_nth or has_free_get_if_nth; + +template +concept has_member_get_nth = requires(T&& var) { + { NEO_FWD(var).template get() } noexcept -> weak_same_as>; +}; + +template +concept has_free_get_nth = sfinae_mask_n, N> and requires(T&& var) { + { get(NEO_FWD(var)) } noexcept -> weak_same_as>; +}; + +template +concept has_any_direct_get_nth_backend = not has_any_try_get_nth_backend + and (has_free_get_nth or has_member_get_nth); + +constexpr inline std::size_t invalid_index = ~std::size_t(0); + +template +constexpr std::size_t lookup_v = invalid_index; + +template + requires((weak_same_as + ...) == 1) +constexpr std::size_t lookup_v, Alt> = meta::find_type_v; + +template , Alt>> +concept can_try_get_alt = N != invalid_index and has_any_try_get_nth_backend; + +template , Alt>> +concept can_direct_get_alt + = N != invalid_index and not can_try_get_alt and has_any_direct_get_nth_backend; + +/* +d8b 888 +Y8P 888 + 888 +888 88888b.d88b. 88888b. 888 +888 888 "888 "88b 888 "88b 888 +888 888 888 888 888 888 888 +888 888 888 888 888 d88P 888 +888 888 888 888 88888P" 888 + 888 + 888 + 888 +*/ + +template +struct try_nth { + template <_get::has_any_try_get_nth_backend T> + NEO_ALWAYS_INLINE constexpr opt_ref_like auto operator()(T&& obj) const noexcept { + if constexpr (has_member_try_get_nth) { + return obj.template try_get(); + } else if constexpr (has_free_try_get_nth) { + return try_get(obj); + } else { + return get_if(NEO_ADDRESSOF(obj)); + } + } +}; + +template +struct nth { + template T> + NEO_ALWAYS_INLINE constexpr forward_nth_type_t operator()(T&& obj) const { + auto oref = try_nth{}(obj); + if (not oref) { + throw std::bad_variant_access(); + } else { + return static_cast>(*oref); + } + } + + template T> + NEO_ALWAYS_INLINE constexpr forward_nth_type_t operator()(T&& obj) const { + if constexpr (has_member_get_nth) { + return NEO_FWD(obj).template get(); + } else { + return get(NEO_FWD(obj)); + } + } +}; + +template +struct try_as { + template T> + NEO_ALWAYS_INLINE constexpr opt_ref_like auto operator()(T&& obj) const noexcept { + constexpr auto N = lookup_v, Alt>; + return try_nth{}(NEO_FWD(obj)); + } +}; + +template +struct as { + template T> + NEO_ALWAYS_INLINE constexpr forward_like_tuple_t operator()(T&& obj) const { + auto opt = try_as{}(obj); + if (not opt) { + throw std::bad_variant_access(); + } else { + return static_cast>(*opt); + } + } + + template T> + NEO_ALWAYS_INLINE constexpr forward_like_tuple_t operator()(T&& obj) const { + constexpr auto N = lookup_v, Alt>; + return nth{}(NEO_FWD(obj)); + } +}; + +template +struct holds_alternative { + static constexpr inline try_as try_it = {}; + + template T> + NEO_ALWAYS_INLINE constexpr bool operator()(const T& obj) const noexcept { + return static_cast(try_it(obj)); + } +}; + +template +struct holds_alternative_n { + static constexpr inline try_nth try_it = {}; + + template T> + NEO_ALWAYS_INLINE constexpr bool operator()(const T& obj) const noexcept { + return static_cast(try_it(obj)); + } +}; + +} // namespace neo::_get diff --git a/src/neo/get.hpp b/src/neo/get.hpp new file mode 100644 index 0000000..df73bdc --- /dev/null +++ b/src/neo/get.hpp @@ -0,0 +1,88 @@ +#pragma once + +#include "./get.detail.hpp" + +#include +#include +#include + +#include +#include + +namespace neo { + +/** + * @brief Attempt to obtain the Nth alternative from a variant-like object + * + * @tparam N The index of the alternative to be requested + */ +template +constexpr inline auto try_get_nth = _get::try_nth{}; + +/** + * @brief Obtain the Nth alternative from a variant-like or tuple-like object + * + * @tparam N The index of the alternative to be requested. + * + * If accessing a variant and the variant does not currently contain the given + * alternative, then bad_variant_access will be raised. + */ +template +constexpr inline auto get_nth = _get::nth{}; + +/** + * @brief Attempt to obtain a given alternative from a variant-like object. + * + * @tparam Alt The type to attempt to obtain from the variant. + */ +template +constexpr inline auto try_get_as = _get::try_as{}; + +/** + * @brief Obtain a given alternative from a variant-like object. + * + * @tparam Alt The type to obtain from the variant. + * + * If the variant does not currently contain the given alternative, then bad_variant_access + * will be raised. + */ +template +constexpr inline auto get_as = _get::as{}; + +/** + * @brief The result of try_get_nth with the given type+index + */ +template +using try_get_nth_t = decltype(try_get_nth(NEO_DECLVAL(V))); + +/** + * @brief The result of get_nth with the given type+index + */ +template +using get_nth_t = decltype(get_nth(NEO_DECLVAL(V))); + +/** + * @brief The result type of try_get_as with the given type+index + */ +template +using try_get_as_t = decltype(try_get_as(NEO_DECLVAL(V))); + +/** + * @brief The result type of get_as with the given type+index + */ +template +using get_as_t = decltype(get_as(NEO_DECLVAL(V))); + +template +concept can_get_nth = requires(Tpl&& tpl) { get_nth(NEO_FWD(tpl)); }; + +template +concept can_get_as = requires(T&& obj) { get_as(NEO_FWD(obj)); }; + +template +constexpr inline auto holds_alternative = _get::holds_alternative{}; + +template +constexpr inline auto holds_alternative_n = _get::holds_alternative_n{}; + +} // namespace neo diff --git a/src/neo/get.test.cpp b/src/neo/get.test.cpp new file mode 100644 index 0000000..ba560bf --- /dev/null +++ b/src/neo/get.test.cpp @@ -0,0 +1,275 @@ +#include "./get.hpp" + +#include + +#include + +#include +#include +#include +#include + +static_assert(neo::_get::has_nth_type, 0>); +static_assert(not neo::_get::has_nth_type, 1>); +static_assert(neo::_get::has_nth_type, 0>); +static_assert(not neo::_get::has_nth_type, 1>); +static_assert(not neo::_get::has_nth_type, 0>); +static_assert(not neo::_get::has_nth_type, 1>); + +static_assert(neo::_get::has_free_get_if_nth, 0>); +static_assert(not neo::_get::has_free_get_if_nth, 1>); + +static_assert(std::same_as, 0>, int*>); +static_assert(std::same_as const, 0>, int const*>); +static_assert(std::same_as const&, 0>, int const*>); +static_assert(std::same_as&&, 0>, int*>); +static_assert(std::same_as&&, 0>, int&&>); +static_assert(std::same_as&, 0>, int&>); +static_assert(std::same_as const&, 0>, const int&>); +static_assert(std::same_as, 0>, int&&>); + +static_assert(std::same_as, int>, int*>); +static_assert(std::same_as const, int>, int const*>); +static_assert(std::same_as const&, int>, int const*>); +static_assert(std::same_as&&, int>, int*>); +static_assert(std::same_as&&, int>, int&&>); +static_assert(std::same_as&, int>, int&>); +static_assert(std::same_as const&, int>, const int&>); +static_assert(std::same_as, int>, int&&>); + +static_assert(std::same_as&&, 0>, int&&>); +static_assert(std::same_as&, 0>, int&>); +static_assert(std::same_as const&, 0>, const int&>); +static_assert(std::same_as, 0>, int&&>); +static_assert(std::same_as&&, int>, int&&>); +static_assert(std::same_as&, int>, int&>); +static_assert(std::same_as const&, int>, const int&>); +static_assert(std::same_as, int>, int&&>); + +TEST_CASE("Get Nth from std::tuple<>") { + STATIC_REQUIRE(neo::can_get_nth, 0>); + STATIC_REQUIRE(neo::can_get_nth&, 0>); + STATIC_REQUIRE(neo::can_get_nth const&, 0>); + STATIC_REQUIRE(neo::can_get_nth&&, 0>); + STATIC_REQUIRE(neo::can_get_nth const&&, 0>); + STATIC_REQUIRE(not neo::can_get_nth, 1>); + STATIC_REQUIRE(not neo::can_get_nth&, 1>); + STATIC_REQUIRE(not neo::can_get_nth const&, 1>); + STATIC_REQUIRE(not neo::can_get_nth&&, 1>); + STATIC_REQUIRE(not neo::can_get_nth const&&, 1>); + + STATIC_REQUIRE(std::same_as, 0>, int&&>); + STATIC_REQUIRE(std::same_as, 0>, int&>); + STATIC_REQUIRE(std::same_as const&, 0>, int&>); + STATIC_REQUIRE(std::same_as const&, 0>, const int&>); + STATIC_REQUIRE(std::same_as&, 0>, const int&>); + STATIC_REQUIRE(std::same_as&&, 0>, const int&>); + STATIC_REQUIRE(std::same_as&&, 0>, int&&>); + STATIC_REQUIRE(std::same_as&, 0>, int&>); +} + +TEST_CASE("Can get T from a std::tuple<>") { + STATIC_REQUIRE(neo::can_get_as, int>); + STATIC_REQUIRE(neo::can_get_as&, int>); + STATIC_REQUIRE(neo::can_get_as const&, int>); + STATIC_REQUIRE(neo::can_get_as&&, int>); + STATIC_REQUIRE(neo::can_get_as const&&, int>); + STATIC_REQUIRE(not neo::can_get_as, char>); + STATIC_REQUIRE(not neo::can_get_as&, char>); + STATIC_REQUIRE(not neo::can_get_as const&, char>); + STATIC_REQUIRE(not neo::can_get_as&&, char>); + STATIC_REQUIRE(not neo::can_get_as const&&, char>); + + // The type T must be exactly an alternative, not cvr allowed: + STATIC_REQUIRE(not neo::can_get_as, int&>); + STATIC_REQUIRE(not neo::can_get_as&, int&>); + STATIC_REQUIRE(not neo::can_get_as const&, int&>); + STATIC_REQUIRE(not neo::can_get_as&&, int&>); + STATIC_REQUIRE(not neo::can_get_as const&&, int&>); + + // Getting from a tuple applies the cvref qualifiers: + STATIC_REQUIRE(std::same_as, int>, int&&>); + STATIC_REQUIRE(std::same_as&, int>, int&>); + STATIC_REQUIRE(std::same_as const&, int>, const int&>); + STATIC_REQUIRE(std::same_as&&, int>, int&&>); + STATIC_REQUIRE(std::same_as const&&, int>, const int&&>); + + // Reference collapsing: + STATIC_REQUIRE(std::same_as, int&>, int&>); + STATIC_REQUIRE(std::same_as&, int&>, int&>); + STATIC_REQUIRE(std::same_as const&, int&>, int&>); + STATIC_REQUIRE(std::same_as&&, int&>, int&>); + STATIC_REQUIRE(std::same_as const&&, int&>, int&>); +} + +TEST_CASE("Get Nth from std::variant<>") { + STATIC_REQUIRE(neo::can_get_nth, 0>); + STATIC_REQUIRE(neo::can_get_nth&, 0>); + STATIC_REQUIRE(neo::can_get_nth const&, 0>); + STATIC_REQUIRE(neo::can_get_nth&&, 0>); + STATIC_REQUIRE(neo::can_get_nth const&&, 0>); + STATIC_REQUIRE(not neo::can_get_nth, 1>); + STATIC_REQUIRE(not neo::can_get_nth&, 1>); + STATIC_REQUIRE(not neo::can_get_nth const&, 1>); + STATIC_REQUIRE(not neo::can_get_nth&&, 1>); + STATIC_REQUIRE(not neo::can_get_nth const&&, 1>); +} + +TEST_CASE("Get T from std::variant<>") { + STATIC_REQUIRE(neo::can_get_as, int>); + STATIC_REQUIRE(neo::can_get_as&, int>); + STATIC_REQUIRE(neo::can_get_as const&, int>); + STATIC_REQUIRE(neo::can_get_as&&, int>); + STATIC_REQUIRE(neo::can_get_as const&&, int>); + STATIC_REQUIRE(not neo::can_get_as, char>); + STATIC_REQUIRE(not neo::can_get_as&, char>); + STATIC_REQUIRE(not neo::can_get_as const&, char>); + STATIC_REQUIRE(not neo::can_get_as&&, char>); + STATIC_REQUIRE(not neo::can_get_as const&&, char>); + + // The type T must be exactly an alternative, no cvr allowed: + STATIC_REQUIRE(not neo::can_get_as, int&>); + STATIC_REQUIRE(not neo::can_get_as&, int&>); + STATIC_REQUIRE(not neo::can_get_as const&, int&>); + STATIC_REQUIRE(not neo::can_get_as&&, int&>); + STATIC_REQUIRE(not neo::can_get_as const&&, int&>); + + // Getting from a variant applies the cvref qualifiers: + STATIC_REQUIRE(std::same_as, int>, int&&>); + STATIC_REQUIRE(std::same_as&, int>, int&>); + STATIC_REQUIRE(std::same_as const&, int>, const int&>); + STATIC_REQUIRE(std::same_as&&, int>, int&&>); + STATIC_REQUIRE(std::same_as const&&, int>, const int&&>); +} + +TEST_CASE("Get Nth from std::pair") { + STATIC_REQUIRE(neo::can_get_nth, 0>); + STATIC_REQUIRE(neo::can_get_nth, 1>); + STATIC_REQUIRE(not neo::can_get_nth, 2>); + + STATIC_REQUIRE(std::same_as, 1>, int&&>); + STATIC_REQUIRE(std::same_as, 1>, int&>); + STATIC_REQUIRE(std::same_as const&, 1>, int&>); + STATIC_REQUIRE(std::same_as const&, 1>, const int&>); + STATIC_REQUIRE(std::same_as&, 1>, const int&>); + STATIC_REQUIRE(std::same_as&&, 1>, const int&>); + STATIC_REQUIRE(std::same_as&&, 1>, int&&>); + STATIC_REQUIRE(std::same_as&, 1>, int&>); +} + +TEST_CASE("Can get T from a std::pair<>") { + STATIC_REQUIRE(neo::can_get_as, int>); + STATIC_REQUIRE(neo::can_get_as&, int>); + STATIC_REQUIRE(neo::can_get_as const&, int>); + STATIC_REQUIRE(neo::can_get_as&&, int>); + STATIC_REQUIRE(neo::can_get_as const&&, int>); + STATIC_REQUIRE(not neo::can_get_as, double>); + STATIC_REQUIRE(not neo::can_get_as&, double>); + STATIC_REQUIRE(not neo::can_get_as const&, double>); + STATIC_REQUIRE(not neo::can_get_as&&, double>); + STATIC_REQUIRE(not neo::can_get_as const&&, double>); + + // The type T must be exactly an alternative, no cvr allowed: + STATIC_REQUIRE(not neo::can_get_as, int&>); + STATIC_REQUIRE(not neo::can_get_as&, int&>); + STATIC_REQUIRE(not neo::can_get_as const&, int&>); + STATIC_REQUIRE(not neo::can_get_as&&, int&>); + STATIC_REQUIRE(not neo::can_get_as const&&, int&>); + + // Getting from a pair applies the cvref qualifiers: + STATIC_REQUIRE(std::same_as, int>, int&&>); + STATIC_REQUIRE(std::same_as&, int>, int&>); + STATIC_REQUIRE(std::same_as const&, int>, const int&>); + STATIC_REQUIRE(std::same_as&&, int>, int&&>); + STATIC_REQUIRE(std::same_as const&&, int>, const int&&>); + + // Reference collapsing: + STATIC_REQUIRE(std::same_as, int&>, int&>); + STATIC_REQUIRE(std::same_as&, int&>, int&>); + STATIC_REQUIRE(std::same_as const&, int&>, int&>); + STATIC_REQUIRE(std::same_as&&, int&>, int&>); + STATIC_REQUIRE(std::same_as const&&, int&>, int&>); +} + +TEST_CASE("Get from std::array") { + using array = std::array; + STATIC_REQUIRE(neo::can_get_nth); + STATIC_REQUIRE(neo::can_get_nth); + STATIC_REQUIRE(not neo::can_get_nth); +} + +struct invalid_getter { + template + using nth_type = int; + + template + constexpr int const& get() & noexcept; + template + constexpr int const& get() const& noexcept; + + template + constexpr int const& get() && noexcept; + template + constexpr int const& get() const&& noexcept; +}; + +struct invalid_ref_getter { + template + using nth_type = int&; + + // All bad: The get should always return `int&` + template + constexpr int const& get() & noexcept; + template + constexpr int const& get() const& noexcept; + template + constexpr int const& get() && noexcept; + template + constexpr int const& get() const&& noexcept; +}; + +struct invalid_ref_getter_v2 { + template + using nth_type = int&; + + // Okay: The getters return ref-to-mutable + template + constexpr int& get() & noexcept; + template + constexpr int& get() const& noexcept; + // Bad: We should not forward rvalue-refs + template + constexpr int&& get() && noexcept; + template + constexpr int&& get() const&& noexcept; +}; + +TEST_CASE("Reject not-tuple-like types") { + // Bad: The non-const getter returns a ref-to-const but the declared type is not `const&` + STATIC_REQUIRE_FALSE(neo::can_get_nth); + // Okay: The const `get` overload does the correct thing + STATIC_REQUIRE(neo::can_get_nth); + + // Bad: The rvalue-getter returns an lvalue reference + STATIC_REQUIRE_FALSE(neo::can_get_nth); + // Bad: The const&& `get` overload does nto return an value-ref-to-const + STATIC_REQUIRE_FALSE(neo::can_get_nth); + + STATIC_REQUIRE_FALSE(neo::can_get_nth); + STATIC_REQUIRE_FALSE(neo::can_get_nth); + STATIC_REQUIRE_FALSE(neo::can_get_nth); + STATIC_REQUIRE_FALSE(neo::can_get_nth); + + STATIC_REQUIRE(neo::can_get_nth); + STATIC_REQUIRE(neo::can_get_nth); + STATIC_REQUIRE_FALSE(neo::can_get_nth); + STATIC_REQUIRE_FALSE(neo::can_get_nth); +} + +neo::testing::cx_test_case TestHoldsAlternative = [](auto check) consteval { + std::variant var; + check(neo::holds_alternative(var)); + check(not neo::holds_alternative(var)); + check(neo::holds_alternative_n<0>(var)); + check(not neo::holds_alternative_n<1>(var)); +}; diff --git a/src/neo/invoke.hpp b/src/neo/invoke.hpp index c01f47e..5d45b9d 100644 --- a/src/neo/invoke.hpp +++ b/src/neo/invoke.hpp @@ -16,9 +16,9 @@ namespace neo { */ template concept simple_invocable = requires(Fn&& fn, Args&&... args) { - NEO_FWD(fn) - (NEO_FWD(args)...); - }; + NEO_FWD(fn) + (NEO_FWD(args)...); +}; namespace invoke_detail { @@ -45,7 +45,7 @@ struct memfun_invoker { DECL_MEMFUN_INV(const&); DECL_MEMFUN_INV(volatile&); DECL_MEMFUN_INV(const volatile&); - DECL_MEMFUN_INV(&noexcept); + DECL_MEMFUN_INV(& noexcept); DECL_MEMFUN_INV(const& noexcept); DECL_MEMFUN_INV(volatile& noexcept); DECL_MEMFUN_INV(const volatile& noexcept); @@ -54,7 +54,7 @@ struct memfun_invoker { DECL_MEMFUN_INV(const&&); DECL_MEMFUN_INV(volatile&&); DECL_MEMFUN_INV(const volatile&&); - DECL_MEMFUN_INV(&&noexcept); + DECL_MEMFUN_INV(&& noexcept); DECL_MEMFUN_INV(const&& noexcept); DECL_MEMFUN_INV(volatile&& noexcept); DECL_MEMFUN_INV(const volatile&& noexcept); @@ -74,11 +74,29 @@ struct call_invoker { NEO_RETURNS(NEO_FWD(fn)(NEO_FWD(args)...)); }; +template +struct pick_invoker_1; + +template <> +struct pick_invoker_1 { + // Invocable is not a member pointer, so defer to the regular calling semantics + template + using f = call_invoker; +}; + +template <> +struct pick_invoker_1 { + // Invocable is a pointer-to-member. + template + using f = conditional_t, + // Invoke as a member function + memfun_invoker, + // "Invoke" as member object + memobj_invoker>; +}; + template > -using pick_invoker_t = conditional_t< - not neo_is_member_pointer(D), - call_invoker, - conditional_t>; +using pick_invoker_t = pick_invoker_1>::template f; } // namespace invoke_detail @@ -96,10 +114,9 @@ struct invoke_fn { /** * @brief "Invoke" an invocable object. Like std::invoke, but cleaner and less debug overhead * - * @tparam Func The invocable. Must be a function, or object that has an operator() overload + * @tparam Func The invocable. Must be a function, or object that has an operator() overload, or a + * pointer-to-member. * @tparam Args The arguments to pass to the invocable. - * - * This is the base overload that will catch things that are callable, including with operator() */ inline constexpr invoke_fn invoke{}; diff --git a/src/neo/like.hpp b/src/neo/like.hpp index 882a2a3..fb886fe 100644 --- a/src/neo/like.hpp +++ b/src/neo/like.hpp @@ -1,96 +1,107 @@ #pragma once -#include +#include "./attrib.hpp" +#include "./type_traits.hpp" namespace neo { namespace like_detail { -template -struct conditional { - template - using eval = F; -}; +template +struct forward_like_impl; template <> -struct conditional { - template - using eval = T; -}; +struct forward_like_impl { + template + using merge = add_lvalue_reference_t>>; -template -concept similar = std::is_same_v, std::remove_cvref_t>; + template + using tuple = add_lvalue_reference_t>; -template -struct copy_ref { - using type = Onto; + template + using language = add_lvalue_reference_t>; }; -template -struct copy_ref { - using type = Onto&&; -}; +template <> +struct forward_like_impl { + template + using merge = add_rvalue_reference_t>>; + + template + using tuple = add_rvalue_reference_t>; -template -struct copy_ref { - using type = Onto&; + template + using language = add_lvalue_reference_t>; }; -template -using copy_ref_t = typename copy_ref::type; +template <> +struct forward_like_impl { + template + using merge = add_lvalue_reference_t>; + + template + using tuple = add_lvalue_reference_t; -template -struct override_ref { template - using eval = T&; + using language = add_lvalue_reference_t; }; template <> -struct override_ref { +struct forward_like_impl { template - using eval = std::remove_reference_t&&; -}; + using merge = add_rvalue_reference_t>; -template -using override_ref_t = typename override_ref>::template eval; + template + using tuple = add_rvalue_reference_t; -template -struct copy_const; + template + using language = add_lvalue_reference_t; +}; template <> -struct copy_const { +struct forward_like_impl : forward_like_impl { template - using eval = copy_ref_t const>; + using language = add_lvalue_reference_t; }; template <> -struct copy_const { +struct forward_like_impl : forward_like_impl { template - using eval = T; + using language = add_lvalue_reference_t>; }; -template -using copy_const_t = - typename copy_const>>::template eval; - -template -using copy_cvref_t = copy_ref_t>; +template +using model = forward_like_impl>, + rvalue_reference_type ? 2 + : lvalue_reference_type ? 1 + : 0>; } // namespace like_detail /** * @brief Merge the cvref-qualifiers of `T` onto `U` - * - * @tparam T - * @tparam U */ template -using forward_like_t - = like_detail::override_ref_t>>; +using forward_like_t = like_detail::model::template merge; -template -constexpr decltype(auto) forward_like(auto&& arg) noexcept { - return static_cast>(arg); +/** + * @brief Use a forward-like as if we were calling get<>() with a tuple. + * + * @tparam Owner The "owner" of the object. + * @tparam T the type to be transformed. + * + * - If `T` is a non-reference type, the cvref qualifiers from `Owner` will be applied + * to `T`. + * - Otherwise, the cv-qualifiers from `Owner` are ignored, and the reference qualifiers + * of `Owner` are concatenated with the reference qualifiers of `T` and the resulting + * collapsed reference type is the final result. + */ +template +using forward_like_tuple_t = like_detail::model::template tuple; + +template +NEO_ALWAYS_INLINE constexpr forward_like_t forward_like(U&& arg) noexcept { + return static_cast>(arg); } } // namespace neo diff --git a/src/neo/meta.hpp b/src/neo/meta.hpp index b4f552a..6171d99 100644 --- a/src/neo/meta.hpp +++ b/src/neo/meta.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include #define u64 unsigned long long @@ -380,12 +383,74 @@ struct remove_prefix_ { struct from; template + requires((sizeof...(Ts) >= N)) struct from> { - static_assert(sizeof...(Ts) >= N, "remove_prefix N is too large"); using type = decltype(remove_prefix_fn::r(static_cast*>(nullptr)...)); }; }; +template <> +struct remove_prefix_<0> { + template + struct from { + using type = L; + }; +}; + +template <> +struct remove_prefix_<1> { + template + struct from; + + template + struct fn { + template + static L r(void*, tag*...); + }; + + template + requires((sizeof...(Ts) >= 1)) + struct from> { + using type = decltype(fn::r(static_cast*>(nullptr)...)); + }; +}; + +template <> +struct remove_prefix_<2> { + template + struct from; + + template + struct fn { + template + static L r(void*, void*, tag*...); + }; + + template + requires((sizeof...(Ts) >= 1)) + struct from> { + using type = decltype(fn::r(static_cast*>(nullptr)...)); + }; +}; + +template <> +struct remove_prefix_<3> { + template + struct from; + + template + struct fn { + template + static L r(void*, void*, void*, tag*...); + }; + + template + requires((sizeof...(Ts) >= 1)) + struct from> { + using type = decltype(fn::r(static_cast*>(nullptr)...)); + }; +}; + } // namespace detail namespace tacit { @@ -404,11 +469,44 @@ struct remove_prefix { template using remove_prefix = tn detail::remove_prefix_::tl from::type; +namespace detail { + +#if NEO_HAS_BUILTIN(__type_pack_element) +template +struct intrin_at_impl; + +template +struct intrin_at_impl> { + template + using f = __type_pack_element; +}; +#endif + +} // namespace detail + +#if NEO_HAS_BUILTIN(__type_pack_element) +/** + * @brief Select the `Nth` element of the given type-list. + * + * @tparam L A list of types to choose from + * @tparam N The zero-based index of the type to be selected. + */ +template +using at = detail::intrin_at_impl::template f; /** - * @brief Obtain the Nth element of the given typelist + * @brief Obtain the `Nth` type from the given list of types (zero-based indexing) + * + * @tparam N The zero-based index of the type to select + * @tparam Ts A list of types to choose from */ +template +using pack_at = __type_pack_element; +#else template using at = head>; +template +using pack_at = at, N>; +#endif namespace tacit { @@ -561,6 +659,51 @@ struct rebind { template using rebind = typename tacit::rebind::tl f; +namespace find_type_detail { + +template +struct find_type_one {}; + +template +struct find_type_one { + enum { value = N }; +}; + +template +struct find_base { + template + struct base {}; +}; + +template <> +struct find_base { + template + struct base { + enum { value = N }; + }; +}; + +template >> +struct finder; + +template +struct finder, std::index_sequence> + : find_base>::template base... {}; + +} // namespace find_type_detail + +template + requires((weak_same_as or ...)) +constexpr std::size_t find_type_v + = find_type_detail::finder, std::index_sequence_for>::value; + +template + requires requires { find_type_detail::finder::value; } +constexpr std::size_t find_type_in = find_type_detail::finder::value; + +template +struct find_type : meta::val> {}; + } // namespace neo::meta #undef u64 diff --git a/src/neo/object_box.hpp b/src/neo/object_box.hpp index 5486907..494a7e6 100644 --- a/src/neo/object_box.hpp +++ b/src/neo/object_box.hpp @@ -1,123 +1,298 @@ #pragma once -#pragma once - #include "./addressof.hpp" #include "./attrib.hpp" #include "./concepts.hpp" #include "./fwd.hpp" #include "./like.hpp" +#include "./type_traits.hpp" -#include +#include +#include #include namespace neo { -namespace _obox_detail { - -template -struct box_base { - /// The exact type that was given for the object_box - using boxed_type = T; - - /// Whether the box contains a scalar type - static constexpr inline bool contains_scalar = scalar_type; - /// Whether the box contains an object type - static constexpr inline bool contains_object = object_type; - /// Whether the box wraps a reference - static constexpr inline bool contains_ref = reference_type; - /// Whether the box wraps a void type - static constexpr inline bool contains_void = void_type; -}; - -} // namespace _obox_detail - /** * @brief Defines a object type that contains a (possibly non-object) type. * * @tparam T Any scalar type, object type, reference type, void type, bounded array type, - * or any cv-qualified type thereof. + * or any cv-qualified type thereof. Unbounded arrays are not supported. * * For object types, inherits the construct/assign requirements of the wrapped * type. * * For references, is trivially copyable, but not default-constructible. * - * For void, is empty and semiregular. + * Defines operator== and operator<=> for applicable types. For references, the + * operators are defined on the equivalent pointer values. For void, all instances + * are equal. + * + * For `void`, is empty and regular. */ template class object_box; -template -class object_box : public _obox_detail::box_base { - // The contained object +namespace detail { + +// Put the ADL-visible specail functions() in a base class for object box, otherwise object_box +// would generate new function templates for every specialization, which can get +// expensive. This is only used for the plain object_type specialization +struct object_box_operators { + template + constexpr friend void swap(object_box& left, + object_box& right) // + noexcept(noexcept(neo::swap(left.get(), right.get()))) { + neo::swap(left.get(), right.get()); + } + + bool operator==(const object_box_operators&) const = default; + auto operator<=>(const object_box_operators&) const = default; +}; + +} // namespace detail + +/** + * Implementation of object_box for non-array object types + */ +template + requires object_type and (not array_type) +class object_box : detail::object_box_operators { NEO_NO_UNIQUE_ADDRESS T _value; +public: + object_box() = default; + + // Defer to the default operators + bool operator==(const object_box&) const = default; + auto operator<=>(const object_box&) const = default; + + /** + * @brief Construct from any type that is explicitly-convertible-to the underlying type. + * + * This constructor is explicit if the underlying conversion is never implicit + */ + template U> + requires explicit_convertible_to + // We are explicit if the implicit conversion is not viable + explicit(not implicit_convertible_to) constexpr object_box(U&& arg) noexcept( + noexcept(T(NEO_FWD(arg)))) + : _value(NEO_FWD(arg)) {} + + /** + * @brief In-place constructor. Calls the underlying constructor directly. + */ + template + requires constructible_from + constexpr explicit object_box(std::in_place_t, + Args&&... args) // + noexcept(noexcept(T(NEO_FWD(args)...))) + : _value(NEO_FWD(args)...) {} + + /// Obtain a reference to the boxed value. + [[nodiscard]] constexpr T& get() & noexcept { return _value; } + [[nodiscard]] constexpr const T& get() const& noexcept { return _value; } + [[nodiscard]] constexpr T&& get() && noexcept { return NEO_MOVE(_value); } + [[nodiscard]] constexpr const T&& get() const&& noexcept { return NEO_MOVE(_value); } + + /** + * @brief Obtain the boxed value as-if by forwarding reference. + */ + [[nodiscard]] constexpr T&& forward() noexcept { return NEO_MOVE(_value); } + [[nodiscard]] constexpr const T&& forward() const noexcept { return NEO_MOVE(_value); } + + constexpr void friend do_repr(auto out, const object_box* self) noexcept { + out.type("[boxed {}]", out.template repr_type("?")); + if (self) { + out.value("{}", out.repr_value(self->get(), "?")); + } + } +}; + +// Implementation of object_box for array types +template +class object_box { + using array_type = Element[Length]; + + // The contained object + NEO_NO_UNIQUE_ADDRESS array_type _array; + // Tag to construct from an array struct _array_construct {}; // In-place construct an array member from a given array template constexpr object_box(_array_construct, Arr&& arr, std::index_sequence) noexcept - : _value{neo::forward_like(arr[Idx])...} {} + : _array{neo::forward_like(arr[Idx])...} {} public: object_box() = default; - // clang-format off - template U> - requires explicit_convertible_to - explicit(not implicit_convertible_to) - constexpr object_box(U&& arg) - noexcept(noexcept(T(NEO_FWD(arg)))) - : _value(NEO_FWD(arg)) {} + /** + * @brief In-place constructor for constructing array elements. + * + * @param args The values for the array elements. Each element is constructed in-place via + * conversion It is required that `args` be the same number of arguments as array elements. + */ + template ... Args> + requires(sizeof...(Args) <= Length) + constexpr explicit object_box(std::in_place_t, Args&&... args) + // We are noexcept if each element conversion is noexcept + noexcept((noexcept(static_cast(NEO_FWD(args))) and ...)) + : _array{NEO_FWD(args)...} {} + + /** + * @brief Array-move-constructor. If the underlying type is an array, construct + * from an array of values of a type that is convertible to element type of + * the wrapped array. + * + * @tparam Elem An element type from which to construct. Must be convertible + * to the underlying array's element type. + * @tparam Len The deduced length of the array argument. + */ + template + requires convertible_to + constexpr explicit object_box(FromElement (&&arr)[OtherLen]) noexcept( + noexcept(static_cast(NEO_DECLVAL(FromElement&&)))) + : object_box(_array_construct{}, NEO_FWD(arr), std::make_index_sequence{}) {} + + /** + * @brief Array-copy-constructor. If the underlying type is an array, construct + * from an array of values of a type that is convertible to element type of + * the wrapped array. + * + * @tparam Elem An element type from which to construct. Must be convertible + * to the underlying array's element type. + * @tparam Len The deduced length of the array argument. + */ + template + requires convertible_to + constexpr explicit object_box(FromElement const (&arr)[OtherLength]) noexcept( + noexcept(static_cast(NEO_DECLVAL(const FromElement&)))) + : object_box(_array_construct{}, NEO_FWD(arr), std::make_index_sequence{}) {} - template - requires array_type - and convertible_to> - constexpr object_box(Elem (&&arr)[Len]) noexcept + // in-place constructor for moving arrays + template + requires convertible_to + constexpr explicit object_box(std::in_place_t, FromElement (&&arr)[Len]) noexcept( + noexcept(static_cast(NEO_DECLVAL(FromElement&&)))) : object_box(_array_construct{}, NEO_FWD(arr), std::make_index_sequence{}) {} - template - requires array_type - and convertible_to> - constexpr object_box(Elem (&arr)[Len]) noexcept + // in-place constructor for copying arrays + template + requires convertible_to + constexpr explicit object_box(std::in_place_t, const FromElement (&arr)[Len]) noexcept( + noexcept(static_cast(NEO_DECLVAL(const FromElement&)))) : object_box(_array_construct{}, NEO_FWD(arr), std::make_index_sequence{}) {} /// Obtain a reference to the boxed value. - [[nodiscard]] constexpr T& get() & noexcept { return _value; } - [[nodiscard]] constexpr const T& get() const& noexcept { return _value; } - [[nodiscard]] constexpr T&& get() && noexcept { return NEO_MOVE(_value); } - [[nodiscard]] constexpr const T&& get() const&& noexcept { return NEO_MOVE(_value); } + [[nodiscard]] constexpr array_type& get() & noexcept { return _array; } + [[nodiscard]] constexpr const array_type& get() const& noexcept { return _array; } + [[nodiscard]] constexpr array_type&& get() && noexcept { return NEO_MOVE(_array); } + [[nodiscard]] constexpr const array_type&& get() const&& noexcept { return NEO_MOVE(_array); } - constexpr T* operator->() noexcept { return neo::addressof(_value); } - constexpr const T* operator->() const noexcept { return neo::addressof(_value); } + /** + * @brief Obtain the boxed value as-if by forwarding reference. + */ + [[nodiscard]] constexpr array_type&& forward() noexcept { return NEO_MOVE(_array); } + [[nodiscard]] constexpr const array_type&& forward() const noexcept { return NEO_MOVE(_array); } constexpr void friend do_repr(auto out, const object_box* self) noexcept { - out.type("[boxed {}]", out.template repr_type("?")); + out.type("[boxed {}]", out.template repr_type("?")); if (self) { out.value("{}", out.repr_value(self->get(), "?")); } } + + // operator== used for arrays of equality-comparable values + constexpr bool operator==(const object_box& other) const noexcept + requires equality_comparable> + { + return _equal(this->_array, other._array); + } + + // operator<=> used for arrays of totally ordered values + constexpr auto operator<=>(const object_box& other) const noexcept + requires totally_ordered> + { + using Cat = std::common_comparison_category_t< + std::compare_three_way_result_t>>; + return _compare(this->_array, other._array); + } + +private: + template + constexpr bool _equal(const E& left, const E& right) const noexcept { + if constexpr (not neo::array_type) { + const bool eq = left == right; + return eq; + } else { + // Compare the two arrays element-by-element + auto iter = left + 0; + auto other_iter = right + 0; + const auto stop = iter + std::extent_v; + for (; iter != stop; ++iter, ++other_iter) { + if (not _equal(*iter, *other_iter)) { + return false; + } + } + return true; + } + } + + template + constexpr Cat _compare(const E& left, const E& right) const noexcept { + if constexpr (not neo::array_type) { + Cat c = std::compare_strong_order_fallback(left, right); + return c; + } else { + auto l_iter = left + 0; + auto r_iter = right + 0; + const auto stop = l_iter + std::extent_v; + Cat r = std::strong_ordering::equal; + for (; l_iter != stop and r == 0; ++l_iter, ++r_iter) { + r = _compare(*l_iter, *r_iter); + } + return r; + } + } }; +/** + * @brief Implementation for reference types. + * + * Assigning to an object_box from another object box will rebind the reference. + * @tparam Ref + */ template -class object_box : public _obox_detail::box_base { +class object_box { using Pointer = add_pointer_t; Pointer _ptr; public: + // boxed references are not default-constructible constexpr object_box() = delete; + // Construct a boxed reference from a compatible referred-to type. template - explicit constexpr object_box(U&& arg) noexcept requires requires(void (*fn)(Pointer)) { - fn(neo::addressof(arg)); - } : _ptr(neo::addressof(arg)) { - } + // Require that we can pointer-convert to the stored type. Checking + // for reference conversion would be unsafe since it could invoke an implicit conversion + // constructor for materializing a temporary + requires convertible_to, Pointer> + explicit constexpr object_box(U&& arg) noexcept + : _ptr(neo::addressof(arg)) {} + + template + requires convertible_to, Pointer> + explicit constexpr object_box(std::in_place_t, U&& arg) noexcept + : _ptr(NEO_ADDRESSOF(arg)) {} /// Obtain the boxed reference [[nodiscard]] constexpr Ref& get() const noexcept { return *_ptr; } + /// Obtain the boxed reference. + [[nodiscard]] constexpr Ref& forward() const noexcept { return *_ptr; } + constexpr Pointer operator->() const noexcept { return _ptr; } constexpr void friend do_repr(auto out, const object_box* self) noexcept { @@ -126,12 +301,26 @@ class object_box : public _obox_detail::box_base { out.value("{}", out.repr_value(self->get(), "?")); } } + + bool operator==(const object_box& other) const = default; + auto operator<=>(const object_box& other) const = default; }; +/** + * @brief Implementation of object_box for void types. + * + * This object_box is default-constructible and empty + */ template -class object_box : public _obox_detail::box_base { +class object_box { public: + object_box() = default; + constexpr explicit object_box(std::in_place_t) noexcept {} + + // Returns void for boxed void constexpr remove_cv_t get() const noexcept {} + // Returns void for boxed void + constexpr remove_cv_t forward() const noexcept {} constexpr void friend do_repr(auto out, const object_box* self) noexcept { out.type("[boxed {}]", out.template repr_type()); @@ -139,8 +328,18 @@ class object_box : public _obox_detail::box_base { out.value("(void)"); } } + + constexpr bool operator==(const object_box&) const noexcept = default; + constexpr auto operator<=>(const object_box&) const noexcept = default; }; +/** + * @brief The sole argument deduction guide for object_box is designed to support + * perfect forwarding of objects. If given an lvalue reference, the deduced box + * is a boxed reference. If given an rvalue, deduces to a box of the value's type. + * + * This will never deduce `void` + */ template object_box(T&& arg) -> object_box; diff --git a/src/neo/object_box.test.cpp b/src/neo/object_box.test.cpp index 56e23a0..c5c16ca 100644 --- a/src/neo/object_box.test.cpp +++ b/src/neo/object_box.test.cpp @@ -76,4 +76,61 @@ TEST_CASE("Array box") { CHECK(box2.get()[0] == 1); CHECK(box2.get()[1] == 2); CHECK(box2.get()[2] == 3); + + neo::object_box box3{std::as_const(arr)}; + static_assert(std::same_as>); + CHECK(box3.get()[0] == 1); + CHECK(box3.get()[1] == 2); + CHECK(box3.get()[2] == 3); + + neo::object_box box_copy_const{std::as_const(carr)}; + static_assert(std::same_as>); + CHECK(box_copy_const.get()[0] == 1); + CHECK(box_copy_const.get()[1] == 2); + CHECK(box_copy_const.get()[2] == 3); + + neo::object_box box_copy_rval{NEO_MOVE(carr)}; + static_assert(std::same_as>); + CHECK(box_copy_rval.get()[0] == 1); + CHECK(box_copy_rval.get()[1] == 2); + CHECK(box_copy_rval.get()[2] == 3); + + neo::object_box box_in_place_construct{std::in_place, carr}; + CHECK(box_in_place_construct.get()[0] == 1); + CHECK(box_in_place_construct.get()[1] == 2); + CHECK(box_in_place_construct.get()[2] == 3); } + +TEST_CASE("Emplacement construct") { + neo::object_box i{std::in_place, 21}; + CHECK(i.get() == 21); +} + +TEST_CASE("Equality+Ordering") { + SECTION("regular") { + constexpr neo::object_box a{31}; + CHECK(a == a); + CHECK_FALSE(a < a); + } + SECTION("Arrays") { + constexpr neo::object_box a{std::in_place, 1, 3, 4}; + STATIC_REQUIRE(a == a); + STATIC_REQUIRE_FALSE(a < a); + constexpr neo::object_box b{std::in_place, 3, 1, 9}; + STATIC_REQUIRE_FALSE(a == b); + STATIC_REQUIRE(a < b); + } + SECTION("void") { + constexpr neo::object_box a; + CHECK(a == a); + CHECK_FALSE(a < a); + } +} + +static_assert(neo::regular>); +static_assert(neo::regular>); +static_assert(neo::totally_ordered>); +static_assert(neo::totally_ordered>); +static_assert(neo::totally_ordered>); +static_assert(neo::totally_ordered>); +static_assert(neo::regular>); diff --git a/src/neo/object_t.hpp b/src/neo/object_t.hpp new file mode 100644 index 0000000..30cd62e --- /dev/null +++ b/src/neo/object_t.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include + +namespace neo { + +namespace detail { + +template +struct object_impl; + +template <> +struct object_impl { + template + using f = T; +}; + +template <> +struct object_impl { + template + using f = reference_object; +}; + +template <> +struct object_impl { + template + using f = unit; +}; + +} // namespace detail + +/** + * @brief Extra-light alternative to object_box + * + * If `T` is an object type, yields `T`. If `T` is `void`, yields `neo::unit`. If `T` is a + * reference type, yields `reference_object`. + */ +template +using object_t + = detail::object_impl:: + template f; + +} // namespace neo diff --git a/src/neo/detail/optional.hpp b/src/neo/optional.detail.hpp similarity index 99% rename from src/neo/detail/optional.hpp rename to src/neo/optional.detail.hpp index c959efe..4585641 100644 --- a/src/neo/detail/optional.hpp +++ b/src/neo/optional.detail.hpp @@ -1,7 +1,7 @@ #pragma once -#include "neo/type_traits.hpp" #include +#include #include diff --git a/src/neo/optional.hpp b/src/neo/optional.hpp index 448450d..92c7a3d 100644 --- a/src/neo/optional.hpp +++ b/src/neo/optional.hpp @@ -1,15 +1,18 @@ #pragma once +#include "./optional.detail.hpp" + #include "./addressof.hpp" #include "./attrib.hpp" -#include "./concepts.hpp" +#include "./constexpr_union.hpp" #include "./declval.hpp" -#include "./detail/optional.hpp" #include "./emplacement.hpp" #include "./invoke.hpp" +#include "./object_t.hpp" #include "./returns.hpp" #include "./storage.hpp" -#include "neo/type_traits.hpp" +#include "./swap.hpp" +#include "./type_traits.hpp" #include #include @@ -40,14 +43,14 @@ class optional : public opt_detail::adl_operators { NEO_NO_UNIQUE_ADDRESS state_type _state = state_type(); /// If we do not currently hold any value, throws bad_optional_access - void _check_has_value() const { + constexpr void _check_has_value() const { if (not has_value()) { opt_detail::throw_bad_optional(); } } /// If we do not currently hold any value, terminate the program. - void _assert_has_value() const noexcept { + constexpr void _assert_has_value() const noexcept { if (not has_value()) { opt_detail::terminate_bad_optional(); } @@ -55,7 +58,7 @@ class optional : public opt_detail::adl_operators { /// Perform a copy-construct/copy-assignment, which may include moving, depending /// on the cvref of "other_storage" and the behavior of our optional_traits - void _assign(auto&& other_storage) { + constexpr void _assign(auto&& other_storage) { if (not has_value()) { // We have no value. We will take on the value of the other if (traits::has_value(other_storage)) { @@ -175,6 +178,12 @@ class optional : public opt_detail::adl_operators { traits::construct(_state, NEO_FWD(args)...); } + constexpr explicit optional(std::in_place_t) noexcept + requires void_type + { + traits::construct(_state); + } + template constexpr explicit(not convertible_to) optional(U&& arg) noexcept(nothrow_constructible_from) @@ -231,7 +240,7 @@ class optional : public opt_detail::adl_operators { constexpr pointer operator->() noexcept { return NEO_ADDRESSOF(**this); } constexpr explicit operator bool() const noexcept { return has_value(); } - constexpr bool has_value() const noexcept { return traits::has_value(_state); } + constexpr bool has_value() const noexcept { return traits::has_value(_state); } constexpr auto value() & -> reference { _check_has_value(); @@ -398,8 +407,8 @@ class optional : public opt_detail::adl_operators { } template - constexpr optional or_else(F&& fn) && - requires movable + constexpr optional or_else(F&& fn) && + requires movable { if (has_value()) { return *NEO_FWD(*this); @@ -420,8 +429,8 @@ explicit optional(const T&) -> optional; template struct default_optional_state { public: - NEO_NO_UNIQUE_ADDRESS storage_for storage; - bool has_value = false; + NEO_NO_UNIQUE_ADDRESS constexpr_union> onion; + bool has_value = false; default_optional_state() = default; }; @@ -466,44 +475,43 @@ struct optional_traits { static constexpr bool trivial_copy = copy_constructible; static constexpr bool trivial_move = move_constructible; - static constexpr bool trivial_copy_assign = copyable; - static constexpr bool trivial_move_assign = movable; + static constexpr bool trivial_copy_assign = trivially_copyable; + static constexpr bool trivial_move_assign = trivially_movable; constexpr static bool has_value(const state_type& st) noexcept { return st.has_value; } constexpr static add_lvalue_reference_t get(state_type& st) noexcept { - return st.storage.get(); + return static_cast>(st.onion._0); } constexpr static add_const_reference_t get(const state_type& st) noexcept { - return st.storage.get(); + return static_cast>(st.onion._0); } constexpr static void destroy(state_type& st) noexcept { - st.storage.destroy(); + st.onion.template destroy<0>(); st.has_value = false; } template constexpr static void construct(state_type& st, Args&&... args) noexcept(nothrow_constructible_from) { - st.storage.construct(NEO_FWD(args)...); + st.onion.template construct<0>(NEO_FWD(args)...); st.has_value = true; } template constexpr static void copy(state_type& into, O&& from) // noexcept(nothrow_constructible_from) // + decltype(NEO_FWD(from).onion._0)>) // { - into.storage.copy_from(NEO_FWD(from).storage); - into.has_value = true; + construct(into, NEO_FWD(from).onion._0); } template - constexpr static void assign(state_type& into, O&& from) // - noexcept(std::is_nothrow_assignable_v) // + constexpr static void assign(state_type& into, O&& from) // + noexcept(std::is_nothrow_assignable_v) // { - into.storage.assign_from(NEO_FWD(from).storage); + into.onion._0 = NEO_FWD(from).onion._0; } - constexpr static void swap(state_type& a, state_type& b) { a.storage.swap(b.storage); } + constexpr static void swap(state_type& a, state_type& b) { neo::swap(a.onion._0, b.onion._0); } }; /** diff --git a/src/neo/pick_type.hpp b/src/neo/pick_type.hpp index f1b3f00..00f5a77 100644 --- a/src/neo/pick_type.hpp +++ b/src/neo/pick_type.hpp @@ -1,208 +1,13 @@ #pragma once -#include +#include "./meta.hpp" namespace neo { -#define u64 unsigned long long +using meta::find_type_v; +using meta::find_type_in; -/** - * @brief Pick the Nth type from a variadic type list - * - * @tparam N The index to pick from - * - * Use the nested `from` struct to pass a variadic list of types - */ -template -struct pick_type; +template +using pick_type_of_t [[deprecated("Use neo::meta::at")]] = meta::at; -template <> -struct pick_type<0> { - template - struct from { - using type = T; - }; -}; - -template <> -struct pick_type<1> { - template - struct from { - using type = T; - }; -}; - -template <> -struct pick_type<2> { - template - struct from { - using type = T; - }; -}; - -template <> -struct pick_type<3> { - template - struct from { - using type = T; - }; -}; - -template -requires(N >= 4 and N < 16) struct pick_type { - template - struct from : pick_type::template from {}; -}; - -template -requires(N >= 16 and N < 64) struct pick_type { - template - struct from : pick_type::template from {}; -}; - -template -requires(N >= 64) struct pick_type { - template - struct from : pick_type::template from {}; -}; - -/** - * @brief Select the Nth type from the list of variadic typs - * - * @tparam N The index (zero-based) - * @tparam Ts Some number of types to read from - */ -template -using pick_type_t = typename pick_type::template from::type; - -/** - * @brief Pick the Nth type argument from a template specialization - * - * @tparam N The index to pick from - */ -template -struct pick_type_of { - /// Specify the template specialization to pick from - template - struct from; - - template