diff --git a/docs/index.md b/docs/index.md index df6f0b7..0db9b0f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -99,16 +99,24 @@ namespace tl constexpr bool operator>=(const U& lhs, const optional<T>& rhs); template <class T> - void swap(optional<T> &lhs, optional<T> + void swap(optional<T> &lhs, optional<T> &rhs); - template <class T> - constexpr optional<detail::decay_t<T>> make_optional(T&& v); + namespace detail + { + struct i_am_secret; + } + + template <class T = detail::i_am_secret, class U, class Ret = detail::conditional_t<std::is_same<T, detail::i_am_secret>::value, detail::decay_t<U>, T>> + constexpr optional<Ret> make_optional(U&& v); template <class T, class ... Args> constexpr optional<T> make_optional(Args&&... args); template <class T, class U, class ... Args> constexpr optional<T> make_optional(std::initializer_list<U> il, Args&&... args); + + template <class T> + class optional<T&>; } namespace std @@ -229,9 +237,9 @@ public: constexpr optional(optional&& rhs) = default; - template <class... Args> constexpr explicit + template <class... Args> constexpr explicit optional(in_place_t, Args&&... args); template <class U, class... Args> - constexpr explicit + constexpr explicit optional(in_place_t, std::initializer_list<U>&, Args&&... args); template <class U=T> constexpr optional(U &&u); @@ -255,9 +263,8 @@ public: template <class ... Args> T& emplace(Args&&... args); - template <class U, class... Args> - T& + T& emplace(std::initializer_list<U> il, Args &&... args); void swap(optional& rhs) noexcept(std::is_nothrow_move_constructible<T>::value&&detail::is_nothrow_swappable<T>::value); @@ -270,7 +277,7 @@ public: constexpr bool has_value() const noexcept; constexpr operator bool() const noexcept; - constexpr T& value() &; + constexpr T &value(); constexpr const T &value() const; template <class U> @@ -323,7 +330,9 @@ Carries out some operation on the stored object if there is one. 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)()`. +*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` @@ -408,7 +417,7 @@ Takes the value out of the optional, leaving it empty Constructs an optional that does not contain a value. -### Constructor `tl::optional::optional` +### Copy constructor `tl::optional::optional`
constexpr optional(const optional& rhs) = default;
@@ -416,7 +425,7 @@ Copy constructor If `rhs` contains a value, the stored value is direct-initialized with it. Otherwise, the constructed optional is empty. -### Constructor `tl::optional::optional` +### Move constructor `tl::optional::optional`
constexpr optional(optional&& rhs) = default;
@@ -426,15 +435,13 @@ If `rhs` contains a value, the stored value is direct-initialized with it. Other ### Function template `tl::optional::optional` -
(1)  template <class... Args> constexpr explicit
+
(1)  template <class... Args> constexpr explicit optional(in_place_t, Args&&... args);
 
 (2)  template <class U, class... Args>
-     constexpr explicit
+ constexpr explicit optional(in_place_t, std::initializer_list<U>&, Args&&... args);
Constructs the stored value in-place using the given arguments. -optional(in\_place\_t, Args&&... args); - ### Function template `tl::optional::optional`
template <class U=T> constexpr optional(U &&u);
@@ -507,17 +514,13 @@ Moves the value from `rhs` if there is one. Otherwise resets the stored value in ### Function template `tl::optional::emplace` -
template <class ... Args>
-T& emplace(Args&&... args);
+
(1)  template <class ... Args>
+     T& emplace(Args&&... args);
 
-Constructs the value in-place, destroying the current one if there is one. \\group emplace
+(2)  template <class U, class... Args>
+     T& emplace(std::initializer_list<U> il, Args &&... args);
-### Function template `tl::optional::emplace` - -
(1)  template <class U, class... Args>
-     T&
- -emplace(std::initializer\_list\ 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 + +----- -----