diff --git a/ostd/environ.hh b/ostd/environ.hh index e65c131..1ede81d 100644 --- a/ostd/environ.hh +++ b/ostd/environ.hh @@ -13,21 +13,21 @@ #include #include +#include -#include "ostd/maybe.hh" #include "ostd/string.hh" /* TODO: make POSIX version thread safe, the Windows version is... */ namespace ostd { -inline Maybe env_get(ConstCharRange name) { +inline std::optional env_get(ConstCharRange name) { char buf[256]; auto tbuf = to_temp_cstr(name, buf, sizeof(buf)); #ifndef OSTD_PLATFORM_WIN32 char const *ret = getenv(tbuf.get()); if (!ret) { - return ostd::nothing; + return std::nullopt; } return std::string{ret}; #else @@ -36,7 +36,7 @@ inline Maybe env_get(ConstCharRange name) { for (;;) { sz = GetEnvironmentVariable(tbuf.get(), rbuf.data(), rbuf.capacity()); if (!sz) { - return ostd::nothing; + return std::nullopt; } if (sz < rbuf.capacity()) { break; diff --git a/ostd/maybe.hh b/ostd/maybe.hh deleted file mode 100644 index 9a2eacd..0000000 --- a/ostd/maybe.hh +++ /dev/null @@ -1,486 +0,0 @@ -/* Option type implementation. Inspired by libc++. - * - * This file is part of OctaSTD. See COPYING.md for futher information. - */ - -#ifndef OSTD_MAYBE_HH -#define OSTD_MAYBE_HH - -#include "ostd/types.hh" -#include "ostd/type_traits.hh" -#include "ostd/memory.hh" -#include "ostd/utility.hh" -#include "ostd/initializer_list.hh" -#include "ostd/functional.hh" - -namespace ostd { - -struct InPlace {}; -constexpr InPlace in_place = InPlace(); - -struct Nothing { - explicit constexpr Nothing(int) {} -}; -constexpr Nothing nothing = Nothing(0); - -namespace detail { - template> - class MaybeStorage { - protected: - using Value = T; - union { - char p_null_state; - Value p_value; - }; - bool p_engaged = false; - - constexpr MaybeStorage(): p_null_state('\0') {} - - MaybeStorage(MaybeStorage const &v): p_engaged(v.p_engaged) { - if (p_engaged) { - ::new(address_of(p_value)) Value(v.p_value); - } - } - - MaybeStorage(MaybeStorage &&v): p_engaged(v.p_engaged) { - if (p_engaged) { - ::new(address_of(p_value)) Value(std::move(v.p_value)); - } - } - - constexpr MaybeStorage(Value const &v): p_value(v), p_engaged(true) {} - constexpr MaybeStorage(Value &&v): p_value(std::move(v)), p_engaged(true) {} - - template - constexpr MaybeStorage(InPlace, A &&...args): - p_value(std::forward(args)...), p_engaged(true) - {} - - ~MaybeStorage() { - if (p_engaged) { - p_value.~Value(); - } - } - }; - - template - class MaybeStorage { - protected: - using Value = T; - union { - char p_null_state; - Value p_value; - }; - bool p_engaged = false; - - constexpr MaybeStorage(): p_null_state('\0') {} - - MaybeStorage(MaybeStorage const &v): p_engaged(v.p_engaged) { - if (p_engaged) { - ::new(address_of(p_value)) Value(v.p_value); - } - } - - MaybeStorage(MaybeStorage &&v): p_engaged(v.p_engaged) { - if (p_engaged) { - ::new(address_of(p_value)) Value(std::move(v.p_value)); - } - } - - constexpr MaybeStorage(Value const &v): p_value(v), p_engaged(true) {} - constexpr MaybeStorage(Value &&v): p_value(std::move(v)), p_engaged(true) {} - - template - constexpr MaybeStorage(InPlace, A &&...args): - p_value(std::forward(args)...), p_engaged(true) - {} - }; -} - -template -class Maybe: private detail::MaybeStorage { - using Base = detail::MaybeStorage; -public: - using Value = T; - - static_assert( - !IsReference, - "Initialization of Maybe with a reference type is not allowed." - ); - static_assert( - !IsSame, InPlace>, - "Initialization of Maybe with InPlace is not allowed." - ); - static_assert( - !IsSame, Nothing>, - "Initialization of Maybe with Nothing is not allowed." - ); - static_assert( - IsObject, - "Initialization of Maybe with non-object type is not allowed." - ); - static_assert( - IsDestructible, - "Initialization of Maybe with a non-destructible object is not allowed." - ); - - constexpr Maybe() {} - Maybe(Maybe const &) = default; - Maybe(Maybe &&) = default; - constexpr Maybe(Nothing) {} - constexpr Maybe(Value const &v): Base(v) {} - constexpr Maybe(Value &&v): Base(std::move(v)) {} - - template>> - constexpr explicit Maybe(InPlace, A &&...args): - Base(in_place, std::forward(args)...) - {} - - template &, A...>> - > - constexpr explicit Maybe(InPlace, std::initializer_list il, A &&...args): - Base(in_place, il, std::forward(args)...) - {} - - ~Maybe() = default; - - Maybe &operator=(Nothing) { - if (this->p_engaged) { - this->p_value.~Value(); - this->p_engaged = false; - } - return *this; - } - - Maybe &operator=(Maybe const &v) { - if (this->p_engaged == v.p_engaged) { - if (this->p_engaged) { - this->p_value = v.p_value; - } - } else { - if (this->p_engaged) { - this->p_value.~Value(); - } else { - ::new(address_of(this->p_value)) Value(v.p_value); - } - this->p_engaged = v.p_engaged; - } - return *this; - } - - Maybe &operator=(Maybe &&v) { - if (this->p_engaged == v.p_engaged) { - if (this->p_engaged) { - this->p_value = std::move(v.p_value); - } - } else { - if (this->p_engaged) { - this->p_value.~Value(); - } else { - ::new(address_of(this->p_value)) Value(std::move(v.p_value)); - } - this->p_engaged = v.p_engaged; - } - return *this; - } - - template, Value> && - IsConstructible && IsAssignable - >> - Maybe &operator=(U &&v) { - if (this->p_engaged) { - this->p_value = std::forward(v); - } else { - ::new(address_of(this->p_value)) Value(std::forward(v)); - this->p_engaged = true; - } - return *this; - } - - template>> - void emplace(A &&...args) { - *this = nothing; - ::new(address_of(this->p_value)) Value(std::forward(args)...); - this->p_engaged = true; - } - - template &, A...> - >> - void emplace(std::initializer_list il, A &&...args) { - *this = nothing; - ::new(address_of(this->p_value)) - Value(il, std::forward(args)...); - this->p_engaged = true; - } - - constexpr Value const *operator->() const { - return address_of(this->p_value); - } - - constexpr Value *operator->() { - return address_of(this->p_value); - } - - constexpr Value const &operator*() const & { - return this->p_value; - } - - constexpr Value &operator*() & { - return this->p_value; - } - - constexpr Value const &&operator*() const && { - return std::move(this->p_value); - } - - constexpr Value &&operator*() && { - return std::move(this->p_value); - } - - constexpr explicit operator bool() const { return this->p_engaged; } - - constexpr Value const &value() const & { - return this->p_value; - } - - constexpr Value &value() & { - return this->p_value; - } - - constexpr Value const &&value() const && { - return std::move(this->p_value); - } - - constexpr Value &&value() && { - return std::move(this->p_value); - } - - template - constexpr Value value_or(U &&v) const & { - static_assert( - IsCopyConstructible, - "Maybe::value_or: T must be copy constructible" - ); - static_assert( - IsConvertible, - "Maybe::value_or: U must be convertible to T" - ); - return this->p_engaged ? this->p_value : Value(std::forward(v)); - } - - template - constexpr Value value_or(U &&v) && { - static_assert( - IsMoveConstructible, - "Maybe::value_or: T must be move constructible" - ); - static_assert( - IsConvertible, - "Maybe::value_or: U must be convertible to T" - ); - return this->p_engaged ? std::move(this->p_value) : Value(std::forward(v)); - } - - void swap(Maybe &v) { - using std::swap; - if (this->p_engaged == v.p_engaged) { - if (this->p_engaged) { - swap(this->p_value, v.p_value); - } - } else { - if (this->p_engaged) { - ::new(address_of(v.p_value)) Value(std::move(this->p_value)); - this->p_value.~Value(); - } else { - ::new(address_of(this->p_value)) Value(std::move(v.p_value)); - v.p_value.~Value(); - } - swap(this->p_engaged, v.p_engaged); - } - } -}; - -template -inline void swap(Maybe &a, Maybe &b) { - a.swap(b); -} - -/* maybe vs maybe */ - -template -inline constexpr bool operator==(Maybe const &a, Maybe const &b) { - return (bool(a) != bool(b)) ? false : (!bool(a) ? true : (*a == *b)); -} - -template -inline constexpr bool operator!=(Maybe const &a, Maybe const &b) { - return !(a == b); -} - -template -inline constexpr bool operator<(Maybe const &a, Maybe const &b) { - return !bool(b) ? false : (!bool(a) ? true : (*a < *b)); -} - -template -inline constexpr bool operator>(Maybe const &a, Maybe const &b) { - return b < a; -} - -template -inline constexpr bool operator<=(Maybe const &a, Maybe const &b) { - return !(b < a); -} - -template -inline constexpr bool operator>=(Maybe const &a, Maybe const &b) { - return !(a < b); -} - -/* maybe vs nothing */ - -template -inline constexpr bool operator==(Maybe const &v, Nothing) { - return !bool(v); -} - -template -inline constexpr bool operator==(Nothing, Maybe const &v) { - return !bool(v); -} - -template -inline constexpr bool operator!=(Maybe const &v, Nothing) { - return bool(v); -} - -template -inline constexpr bool operator!=(Nothing, Maybe const &v) { - return bool(v); -} - -template -inline constexpr bool operator<(Maybe const &, Nothing) { - return false; -} - -template -inline constexpr bool operator<(Nothing, Maybe const &v) { - return bool(v); -} - -template -inline constexpr bool operator<=(Maybe const &v, Nothing) { - return !bool(v); -} - -template -inline constexpr bool operator<=(Nothing, Maybe const &) { - return true; -} - -template -inline constexpr bool operator>(Maybe const &v, Nothing) { - return bool(v); -} - -template -inline constexpr bool operator>(Nothing, Maybe const &) { - return false; -} - -template -inline constexpr bool operator>=(Maybe const &, Nothing) { - return true; -} - -template -inline constexpr bool operator>=(Nothing, Maybe const &v) { - return !bool(v); -} - -/* maybe vs T */ - -template -inline constexpr bool operator==(Maybe const &a, T const &b) { - return bool(a) ? (*a == b) : false; -} - -template -inline constexpr bool operator==(T const &b, Maybe const &a) { - return bool(a) ? (*a == b) : false; -} - -template -inline constexpr bool operator!=(Maybe const &a, T const &b) { - return bool(a) ? !(*a == b) : true; -} - -template -inline constexpr bool operator!=(T const &b, Maybe const &a) { - return bool(a) ? !(*a == b) : true; -} - -template -inline constexpr bool operator<(Maybe const &a, T const &b) { - return bool(a) ? Less()(*a, b) : true; -} - -template -inline constexpr bool operator<(T const &b, Maybe const &a) { - return bool(a) ? Less()(b, *a) : false; -} - -template -inline constexpr bool operator<=(Maybe const &a, T const &b) { - return !(a > b); -} - -template -inline constexpr bool operator<=(T const &b, Maybe const &a) { - return !(b > a); -} - -template -inline constexpr bool operator>(Maybe const &a, T const &b) { - return bool(a) ? (b < a) : true; -} - -template -inline constexpr bool operator>(T const &b, Maybe const &a) { - return bool(a) ? (a < b) : true; -} - -template -inline constexpr bool operator>=(Maybe const &a, T const &b) { - return !(a < b); -} - -template -inline constexpr bool operator>=(T const &b, Maybe const &a) { - return !(b < a); -} - -/* make maybe */ - -template -inline constexpr Maybe> make_maybe(T &&v) { - return Maybe>(std::forward(v)); -} - -template -inline constexpr Maybe make_maybe(A &&...args) { - return Maybe(in_place, std::forward(args)...); -} - -template -inline constexpr Maybe make_maybe(std::initializer_list il, A &&...args) { - return Maybe(in_place, il, std::forward(args)...); -} - -} /* namespace ostd */ - -#endif