diff --git a/sprout/optional.hpp b/sprout/optional.hpp index 9a96f951..142e2f38 100644 --- a/sprout/optional.hpp +++ b/sprout/optional.hpp @@ -1,5 +1,5 @@ /*============================================================================= - Copyright (c) 2011-2017 Bolero MURAKAMI + Copyright (c) 2011-2016 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -14,10 +14,10 @@ #include #include #include +#include #include #include #include -#include #include #endif // #ifndef SPROUT_OPTIONAL_HPP diff --git a/sprout/utility.hpp b/sprout/utility.hpp index 79752496..5e46d4d8 100644 --- a/sprout/utility.hpp +++ b/sprout/utility.hpp @@ -23,5 +23,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_UTILITY_HPP diff --git a/sprout/utility/fold.hpp b/sprout/utility/fold.hpp new file mode 100644 index 00000000..3afc7b2d --- /dev/null +++ b/sprout/utility/fold.hpp @@ -0,0 +1,98 @@ +/*============================================================================= + Copyright (c) 2011-2017 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_UTILITY_FOLD_HPP +#define SPROUT_UTILITY_FOLD_HPP + +#include +#include +#include + +namespace sprout { + template + class folder_forwarder { + public: + typedef BinaryOperation function_type; + private: + function_type binary_op_; + public: + explicit SPROUT_CONSTEXPR folder_forwarder(function_type const& binary_op) + : binary_op_(binary_op) + {} + SPROUT_CONSTEXPR function_type const& func() const { + return binary_op_; + } + }; + + template + class folder { + public: + typedef BinaryOperation function_type; + typedef T value_type; + private: + function_type binary_op_; + value_type value_; + public: + explicit SPROUT_CONSTEXPR folder(function_type const& binary_op, value_type const& value) + : binary_op_(binary_op), value_(value) + {} + template + SPROUT_CXX14_CONSTEXPR folder& left(U&& val) { + return (value_ = binary_op_(value_, SPROUT_FORWARD(U, val))), *this; + } + template + SPROUT_CXX14_CONSTEXPR folder& right(U&& val) { + return (value_ = binary_op_(SPROUT_FORWARD(U, val), value_)), *this; + } + SPROUT_CONSTEXPR function_type const& func() const { + return binary_op_; + } + SPROUT_CONSTEXPR value_type value() const { + return value_; + } + SPROUT_CONSTEXPR value_type get() const { + return value_; + } + SPROUT_CONSTEXPR operator value_type() const { + return value_; + } + }; + + template + inline SPROUT_CONSTEXPR sprout::folder + operator,(sprout::folder_forwarder const& lhs, T&& rhs) { + return sprout::folder(lhs.func(), SPROUT_FORWARD(T, rhs)); + } + template + inline SPROUT_CONSTEXPR sprout::folder + operator,(T&& lhs, sprout::folder_forwarder const& rhs) { + return sprout::folder(rhs.func(), SPROUT_FORWARD(T, lhs)); + } + template + inline SPROUT_CONSTEXPR sprout::folder&& + operator,(sprout::folder&& lhs, U&& rhs) { + return sprout::move(lhs.left(SPROUT_FORWARD(U, rhs))); + } + template + inline SPROUT_CONSTEXPR sprout::folder&& + operator,(U&& lhs, sprout::folder&& rhs) { + return sprout::move(rhs.right(SPROUT_FORWARD(U, lhs))); + } + + template + inline SPROUT_CONSTEXPR sprout::folder_forwarder + fold_by(BinaryOperation const& binary_op) { + return sprout::folder_forwarder(binary_op); + } + template + inline SPROUT_CONSTEXPR sprout::folder + fold_by(BinaryOperation const& binary_op, T&& init) { + return sprout::folder(binary_op, SPROUT_FORWARD(T, init)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_FOLD_HPP diff --git a/sprout/utility/value_holder.hpp b/sprout/utility/value_holder.hpp index d98e0ca3..b0198bbf 100644 --- a/sprout/utility/value_holder.hpp +++ b/sprout/utility/value_holder.hpp @@ -1,5 +1,5 @@ /*============================================================================= - Copyright (c) 2011-2017 Bolero MURAKAMI + Copyright (c) 2011-2016 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -10,7 +10,11 @@ #include #include +#include +#include #include #include +#include +#include #endif // #ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP diff --git a/sprout/utility/value_holder/comparison.hpp b/sprout/utility/value_holder/comparison.hpp new file mode 100644 index 00000000..9affc64d --- /dev/null +++ b/sprout/utility/value_holder/comparison.hpp @@ -0,0 +1,56 @@ +/*============================================================================= + Copyright (c) 2011-2016 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_UTILITY_VALUE_HOLDER_COMPARISON_HPP +#define SPROUT_UTILITY_VALUE_HOLDER_COMPARISON_HPP + +#include +#include +#include + +namespace sprout { + // + // operator== + // operator!= + // operator< + // operator> + // operator<= + // operator>= + // + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::value_holder const& lhs, sprout::value_holder const& rhs) { + return sprout::equal_pointees(lhs, rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::value_holder const& lhs, sprout::value_holder const& rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::value_holder const& lhs, sprout::value_holder const& rhs) { + return sprout::less_pointees(lhs, rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::value_holder const& lhs, sprout::value_holder const& rhs) { + return rhs < lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::value_holder const& lhs, sprout::value_holder const& rhs) { + return !(rhs < lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::value_holder const& lhs, sprout::value_holder const& rhs) { + return !(lhs < rhs); + } +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_VALUE_HOLDER_COMPARISON_HPP diff --git a/sprout/utility/value_holder/io.hpp b/sprout/utility/value_holder/io.hpp new file mode 100644 index 00000000..4c80c220 --- /dev/null +++ b/sprout/utility/value_holder/io.hpp @@ -0,0 +1,74 @@ +/*============================================================================= + Copyright (c) 2011-2016 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_UTILITY_VALUE_HOLDER_IO_HPP +#define SPROUT_UTILITY_VALUE_HOLDER_IO_HPP + +#include +#include +#include +#include + +namespace sprout { + // + // operator>> + // + template + inline SPROUT_NON_CONSTEXPR std::basic_istream& + operator>>(std::basic_istream& lhs, sprout::value_holder& rhs) { + if (lhs.good()) { + int d = lhs.get(); + if (d == ' ') { + T x; + lhs >> x; + rhs = x; + } else { + lhs.setstate(std::ios::failbit); + } + } + return lhs; + } + template + inline SPROUT_NON_CONSTEXPR std::basic_istream& + operator>>(std::basic_istream& lhs, sprout::value_holder& rhs) { + if (lhs.good()) { + int d = lhs.get(); + if (d == ' ') { + T x; + lhs >> x; + rhs = x; + } else { + if (d == '-') { + d = lhs.get(); + if (d == '-') { + rhs = sprout::value_holder(); + return lhs; + } + } + lhs.setstate(std::ios::failbit); + } + } + return lhs; + } + // + // operator<< + // + template + inline SPROUT_NON_CONSTEXPR std::basic_ostream& + operator<<(std::basic_ostream& lhs, sprout::value_holder const& rhs) { + if (lhs.good()) { + if (!rhs) { + lhs << "--"; + } else { + lhs << ' ' << *rhs; + } + } + return lhs; + } +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_VALUE_HOLDER_IO_HPP diff --git a/sprout/utility/value_holder/value_holder.hpp b/sprout/utility/value_holder/value_holder.hpp index 9aaf2b12..0e09b6d8 100644 --- a/sprout/utility/value_holder/value_holder.hpp +++ b/sprout/utility/value_holder/value_holder.hpp @@ -1,5 +1,5 @@ /*============================================================================= - Copyright (c) 2011-2017 Bolero MURAKAMI + Copyright (c) 2011-2016 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -11,12 +11,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include namespace sprout { namespace detail { @@ -44,10 +46,10 @@ namespace sprout { static SPROUT_CONSTEXPR holder_type&& hold(movable_param_type p) SPROUT_NOEXCEPT { return sprout::move(p); } - static SPROUT_CONSTEXPR reference ref(holder_type& r) { + static SPROUT_CONSTEXPR reference ref(holder_type& r) SPROUT_NOEXCEPT { return r; } - static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { + static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) SPROUT_NOEXCEPT { return r; } static SPROUT_CONSTEXPR pointer ptr(holder_type& r) SPROUT_NOEXCEPT { @@ -81,11 +83,11 @@ namespace sprout { static SPROUT_CONSTEXPR holder_type const&& hold(movable_param_type p) SPROUT_NOEXCEPT { return sprout::move(p); } - static SPROUT_CONSTEXPR reference ref(holder_type& r) { - return *r; + static SPROUT_CONSTEXPR reference ref(holder_type& r) SPROUT_NOEXCEPT { + return r; } - static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { - return *r; + static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) SPROUT_NOEXCEPT { + return r; } static SPROUT_CONSTEXPR pointer ptr(holder_type& r) SPROUT_NOEXCEPT { return sprout::addressof(r); @@ -116,7 +118,9 @@ namespace sprout { return sprout::addressof(p); } static SPROUT_CONSTEXPR reference ref(holder_type r) { - return *r; + return r ? *r + : (throw sprout::bad_optional_access("value_holder<>: bad optional access"), *r) + ; } static SPROUT_CONSTEXPR pointer ptr(holder_type r) SPROUT_NOEXCEPT { return r; @@ -144,7 +148,9 @@ namespace sprout { return sprout::addressof(p); } static SPROUT_CONSTEXPR reference ref(holder_type r) { - return *r; + return r ? *r + : (throw sprout::bad_optional_access("value_holder<>: bad optional access"), *r) + ; } static SPROUT_CONSTEXPR pointer ptr(holder_type r) SPROUT_NOEXCEPT { return r; @@ -306,6 +312,13 @@ namespace sprout { SPROUT_CONSTEXPR mutable_or_const_pointer get_ptr() const SPROUT_NOEXCEPT { return get_pointer(); } + + SPROUT_EXPLICIT_CONVERSION SPROUT_CONSTEXPR operator bool() const SPROUT_NOEXCEPT { + return is_initialized(); + } + SPROUT_CONSTEXPR bool operator!() const SPROUT_NOEXCEPT { + return !is_initialized(); + } SPROUT_CONSTEXPR bool is_initialized() const SPROUT_NOEXCEPT { return !!get_pointer(); }