il, Args &&... args);
+Constructs the value in-place, destroying the current one if there is one.
### Function `tl::optional::swap`
@@ -557,14 +560,12 @@ If neither optionals have a value, nothing happens. If both have a value, the va
### Function `tl::optional::value`
-(1) constexpr T& value() &;
+(1) constexpr T &value();
(2) constexpr const T &value() const;
*Returns*: the contained value if there is one, otherwise throws \[bad\_optional\_access\]
-synopsis constexpr T \&value();
-
### Function template `tl::optional::value_or`
(1) template <class U>
@@ -691,11 +692,385 @@ Compares the optional with a value.
If the optional has a value, it is compared with the other value using `T`s relational operators. Otherwise, the optional is considered less than the value.
-## Function template `tl::swap`
+## Class template `tl::optional`
template <class T>
-void swap(optional<T> &lhs, optional<T>
+class optional<T&>
+{
+public:
+ template <class F>
+ constexpr auto and_then(F &&f) &;
+ template <class F>
+ constexpr auto and_then(F &&f) &&;
+ template <class F>
+ constexpr auto and_then(F &&f) const &;
+ template <class F>
+ constexpr auto and_then(F &&f) const &&;
+
+ template <class F> constexpr auto map(F &&f) &;
+ template <class F> constexpr auto map(F &&f) &&;
+ template <class F> constexpr auto map(F &&f) const&;
+ template <class F> constexpr auto map(F &&f) const&&;
+
+ template <class F> optional<T> or_else (F &&f) &;
+ template <class F> optional<T> or_else (F &&f) &&;
+ template <class F> optional<T> or_else (F &&f) const &;
+
+ template <class F, class U>
+ U map_or(F&& f, U&& u) &;
+ template <class F, class U>
+ U map_or(F&& f, U&& u) &&;
+ template <class F, class U>
+ U map_or(F&& f, U&& u) const &;
+ template <class F, class U>
+ U map_or(F&& f, U&& u) const &&;
+
+ template <class F, class U>
+ auto map_or_else(F &&f, U &&u) &;
+ template <class F, class U>
+ auto map_or_else(F &&f, U &&u)
+ template <class F, class U>
+ auto map_or_else(F &&f, U &&u)
+ template <class F, class U>
+ auto map_or_else(F &&f, U &&u)
+
+ template <class U>
+ constexpr optional<typename std::decay<U>::type> conjunction(U&& u) const;
+
+ constexpr optional disjunction(const optional& rhs) &;
+ constexpr optional disjunction(const optional& rhs) const &;
+ constexpr optional disjunction(const optional& rhs) &&;
+ constexpr optional disjunction(const optional& rhs) const &&;
+ constexpr optional disjunction(optional&& rhs) &;
+ constexpr optional disjunction(optional&& rhs) const &;
+ constexpr optional disjunction(optional&& rhs) &&;
+ constexpr optional disjunction(optional&& rhs) const &&;
+
+ optional take() &;
+ optional take() const &;
+ optional take() &&;
+ optional take() const &&;
+
+ using value_type = T&;
+
+ constexpr optional() noexcept;
+ constexpr optional(nullopt_t) noexcept;
+
+ constexpr optional(const optional& rhs) noexcept = default;
+
+ constexpr optional(optional&& rhs) = default;
+
+ template <class U=T> constexpr optional(U &&u);
+
+ ~optional() = default;
+
+ optional& operator=(nullopt_t) noexcept;
+
+ optional& operator=(const optional& rhs) = default;
+
+ optional &operator=(U &&u);
+
+ template <class U>
+ optional& operator=(const optional<U>& rhs);
+
+ template <class ... Args>
+ T& emplace(Args&&... args) noexcept;
+
+ void swap(optional& rhs) noexcept;
+
+ constexpr const T *operator->() const;
+ constexpr T *operator->();
+
+ constexpr T &operator*();
+ constexpr const T &operator*() const;
+
+ constexpr bool has_value() const noexcept;
+ constexpr operator bool() const noexcept;
+
+ constexpr T& value() &;
+ constexpr const T &value() const;
+
+ template <class U>
+ constexpr T value_or(U&& u) const &;
+ template <class U>
+ constexpr T value_or(U&& u) &&;
+
+ void reset() noexcept;
+};
-\&rhs);
+Specialization for when `T` is a reference. `optional` acts similarly to a `T*`, but provides more operations and shows intent more clearly.
+
+*Examples*:
+
+ int i = 42;
+ tl::optional o = i;
+ *o == 42; //true
+ i = 12;
+ *o = 12; //true
+ &*o == &i; //true
+
+Assignment has rebind semantics rather than assign-through semantics:
+
+ int j = 8;
+ o = j;
+
+ &*o == &j; //true
+
+### Function template `tl::optional::and_then`
+
+(1) template <class F>
+ constexpr auto and_then(F &&f) &;
+
+(2) template <class F>
+ constexpr auto and_then(F &&f) &&;
+
+(3) template <class F>
+ constexpr auto and_then(F &&f) const &;
+
+(4) template <class F>
+ constexpr auto and_then(F &&f) const &&;
+
+Carries out some operation which returns an optional on the stored object if there is one. \\requires `std::invoke(std::forward(f), value())` returns a `std::optional` for some `U`. \\returns Let `U` be the result of `std::invoke(std::forward(f), value())`. Returns a `std::optional`. The return value is empty if `*this` is empty, otherwise the return value of `std::invoke(std::forward(f), value())` is returned.
+
+### Function template `tl::optional::map`
+
+(1) template <class F> constexpr auto map(F &&f) &;
+
+(2) template <class F> constexpr auto map(F &&f) &&;
+
+(3) template <class F> constexpr auto map(F &&f) const&;
+
+(4) template <class F> constexpr auto map(F &&f) const&&;
+
+Carries out some operation on the stored object if there is one.
+
+*Returns*: Let `U` be the result of `std::invoke(std::forward(f), value())`. Returns a `std::optional`. The return value is empty if `*this` is empty, otherwise an `optional` is constructed from the return value of `std::invoke(std::forward(f), value())` and is returned.
+
+### Function template `tl::optional::or_else`
+
+(1) template <class F> optional<T> or_else (F &&f) &;
+
+(2) template <class F> optional<T> or_else (F &&f) &&;
+
+(3) template <class F> optional<T> or_else (F &&f) const &;
+
+Calls `f` if the optional is empty
+
+*Requires*: `std::invoke_result_t` must be void or convertible to `optional`. \\effects If `*this` has a value, returns `*this`. Otherwise, if `f` returns `void`, calls `std::forward(f)` and returns `std::nullopt`. Otherwise, returns `std::forward(f)()`.
+
+### Function template `tl::optional::map_or`
+
+(1) template <class F, class U>
+ U map_or(F&& f, U&& u) &;
+
+(2) template <class F, class U>
+ U map_or(F&& f, U&& u) &&;
+
+(3) template <class F, class U>
+ U map_or(F&& f, U&& u) const &;
+
+(4) template <class F, class U>
+ U map_or(F&& f, U&& u) const &&;
+
+Maps the stored value with `f` if there is one, otherwise returns `u`.
+
+If there is a value stored, then `f` is called with `**this` and the value is returned. Otherwise `u` is returned.
+
+### Function template `tl::optional::map_or_else`
+
+(1) template <class F, class U>
+ auto map_or_else(F &&f, U &&u) &;
+
+(2) template <class F, class U>
+ auto map_or_else(F &&f, U &&u)
+
+(3) template <class F, class U>
+ auto map_or_else(F &&f, U &&u)
+
+(4) template <class F, class U>
+ auto map_or_else(F &&f, U &&u)
+
+Maps the stored value with `f` if there is one, otherwise calls `u` and returns the result.
+
+If there is a value stored, then `f` is called with `**this` and the value is returned. Otherwise `std::forward(u)()` is returned.
+
+### Function template `tl::optional::conjunction`
+
+template <class U>
+constexpr optional<typename std::decay<U>::type> conjunction(U&& u) const;
+
+*Returns*: `u` if `*this` has a value, otherwise an empty optional.
+
+### Function `tl::optional::disjunction`
+
+(1) constexpr optional disjunction(const optional& rhs) &;
+
+(2) constexpr optional disjunction(const optional& rhs) const &;
+
+(3) constexpr optional disjunction(const optional& rhs) &&;
+
+(4) constexpr optional disjunction(const optional& rhs) const &&;
+
+(5) constexpr optional disjunction(optional&& rhs) &;
+
+(6) constexpr optional disjunction(optional&& rhs) const &;
+
+(7) constexpr optional disjunction(optional&& rhs) &&;
+
+(8) constexpr optional disjunction(optional&& rhs) const &&;
+
+*Returns*: `rhs` if `*this` is empty, otherwise the current value.
+
+### Function `tl::optional::take`
+
+(1) optional take() &;
+
+(2) optional take() const &;
+
+(3) optional take() &&;
+
+(4) optional take() const &&;
+
+Takes the value out of the optional, leaving it empty
+
+### Default constructor `tl::optional::optional`
+
+(1) constexpr optional() noexcept;
+
+(2) constexpr optional(nullopt_t) noexcept;
+
+Constructs an optional that does not contain a value.
+
+### Copy constructor `tl::optional::optional`
+
+constexpr optional(const optional& rhs) noexcept = default;
+
+Copy constructor
+
+If `rhs` contains a value, the stored value is direct-initialized with it. Otherwise, the constructed optional is empty.
+
+### Move constructor `tl::optional::optional`
+
+constexpr optional(optional&& rhs) = default;
+
+Move constructor
+
+If `rhs` contains a value, the stored value is direct-initialized with it. Otherwise, the constructed optional is empty.
+
+### Function template `tl::optional::optional`
+
+template <class U=T> constexpr optional(U &&u);
+
+Constructs the stored value with `u`.
+
+### Destructor `tl::optional::~optional`
+
+~optional() = default;
+
+No-op
+
+### Assignment operator `tl::optional::operator=`
+
+optional& operator=(nullopt_t) noexcept;
+
+Assignment to empty.
+
+Destroys the current value if there is one.
+
+### Copy assignment operator `tl::optional::operator=`
+
+optional& operator=(const optional& rhs) = default;
+
+Copy assignment.
+
+Rebinds this optional to the referee of `rhs` if there is one. Otherwise resets the stored value in `*this`.
+
+### Assignment operator `tl::optional::operator=`
+
+optional &operator=(U &&u);
+
+Rebinds this optional to `u`.
+
+*Requires*: `U` must be an lvalue reference.
+
+### Assignment operator `tl::optional::operator=`
+
+template <class U>
+optional& operator=(const optional<U>& rhs);
+
+Converting copy assignment operator.
+
+Rebinds this optional to the referee of `rhs` if there is one. Otherwise resets the stored value in `*this`.
+
+### Function template `tl::optional::emplace`
+
+(1) template <class ... Args>
+ T& emplace(Args&&... args) noexcept;
+
+Constructs the value in-place, destroying the current one if there is one.
+
+### Function `tl::optional::swap`
+
+void swap(optional& rhs) noexcept;
+
+Swaps this optional with the other.
+
+If neither optionals have a value, nothing happens. If both have a value, the values are swapped. If one has a value, it is moved to the other and the movee is left valueless.
+
+### Operator `tl::optional::operator->`
+
+(1) constexpr const T *operator->() const;
+
+(2) constexpr T *operator->();
+
+*Returns*: a pointer to the stored value
+
+*Requires*: a value is stored
+
+### Operator `tl::optional::operator*`
+
+(1) constexpr T &operator*();
+
+(2) constexpr const T &operator*() const;
+
+*Returns*: the stored value
+
+*Requires*: a value is stored
+
+### Function `tl::optional::has_value`
+
+(1) constexpr bool has_value() const noexcept;
+
+(2) constexpr operator bool() const noexcept;
+
+*Returns*: whether or not the optional has a value
+
+### Function `tl::optional::value`
+
+(1) constexpr T& value() &;
+
+(2) constexpr const T &value() const;
+
+*Returns*: the contained value if there is one, otherwise throws \[bad\_optional\_access\]
+
+synopsis constexpr T \&value();
+
+### Function template `tl::optional::value_or`
+
+(1) template <class U>
+ constexpr T value_or(U&& u) const &;
+
+(2) template <class U>
+ constexpr T value_or(U&& u) &&;
+
+*Returns*: the stored value if there is one, otherwise returns `u`
+
+### Function `tl::optional::reset`
+
+void reset() noexcept;
+
+Destroys the stored value if one exists, making the optional empty
+
+-----
-----