From 8cb432dee138cc2c63bd27f15840def565550e81 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Mon, 22 Oct 2012 23:10:11 +0900 Subject: [PATCH] add sprout::optional --- sprout/config/auto_config.hpp | 2 + sprout/config/compiler.hpp | 2 + sprout/config/compiler/cxx11.hpp | 20 +++ sprout/config/config.hpp | 82 +----------- sprout/config/suffix.hpp | 83 ++++++++++++ sprout/none.hpp | 17 +++ sprout/optional.hpp | 11 ++ sprout/optional/comparison.hpp | 49 ++++++++ sprout/optional/get.hpp | 61 +++++++++ sprout/optional/io.hpp | 53 ++++++++ sprout/optional/make_optional.hpp | 23 ++++ sprout/optional/optional.hpp | 187 ++++++++++++++++++++++++++++ sprout/utility.hpp | 3 +- sprout/utility/compare_pointees.hpp | 51 ++++++++ sprout/utility/value_holder.hpp | 11 ++ 15 files changed, 574 insertions(+), 81 deletions(-) create mode 100644 sprout/config/compiler/cxx11.hpp create mode 100644 sprout/config/suffix.hpp create mode 100644 sprout/none.hpp create mode 100644 sprout/optional.hpp create mode 100644 sprout/optional/comparison.hpp create mode 100644 sprout/optional/get.hpp create mode 100644 sprout/optional/io.hpp create mode 100644 sprout/optional/make_optional.hpp create mode 100644 sprout/optional/optional.hpp create mode 100644 sprout/utility/compare_pointees.hpp diff --git a/sprout/config/auto_config.hpp b/sprout/config/auto_config.hpp index 2d81945d..648bfebb 100644 --- a/sprout/config/auto_config.hpp +++ b/sprout/config/auto_config.hpp @@ -78,4 +78,6 @@ # define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION #endif // #ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION +#include + #endif // #ifndef SPROUT_CONFIG_AUTO_CONFIG_HPP diff --git a/sprout/config/compiler.hpp b/sprout/config/compiler.hpp index bb457db9..ddb20121 100644 --- a/sprout/config/compiler.hpp +++ b/sprout/config/compiler.hpp @@ -47,4 +47,6 @@ # include #endif +#include + #endif // #ifndef SPROUT_CONFIG_COMPILER_HPP diff --git a/sprout/config/compiler/cxx11.hpp b/sprout/config/compiler/cxx11.hpp new file mode 100644 index 00000000..1e2cee6b --- /dev/null +++ b/sprout/config/compiler/cxx11.hpp @@ -0,0 +1,20 @@ +#ifndef SPROUT_CONFIG_COMPILER_CXX11_HPP +#define SPROUT_CONFIG_COMPILER_CXX11_HPP + +#ifdef SPROUT_NO_CONSTEXPR +# define SPROUT_NO_CXX11_CONSTEXPR +#endif +#ifdef SPROUT_NO_NOEXCEPT +# define SPROUT_NO_CXX11_CNOEXCEPT +#endif +#ifdef SPROUT_NO_TEMPLATE_ALIASES +# define SPROUT_NO_CXX11_CTEMPLATE_ALIASES +#endif +#ifdef SPROUT_NO_USER_DEFINED_LITERALS +# define SPROUT_NO_CXX11_CUSER_DEFINED_LITERALS +#endif +#ifdef SPROUT_NO_DELEGATING_CONSTRUCTORS +# define SPROUT_NO_CXX11_CDELEGATING_CONSTRUCTORS +#endif + +#endif // #ifndef SPROUT_CONFIG_COMPILER_CXX11_HPP diff --git a/sprout/config/config.hpp b/sprout/config/config.hpp index 24374ca2..1c9fa0f0 100644 --- a/sprout/config/config.hpp +++ b/sprout/config/config.hpp @@ -1,89 +1,11 @@ #ifndef SPROUT_CONFIG_CONFIG_HPP #define SPROUT_CONFIG_CONFIG_HPP -#include - #ifndef SPROUT_CONFIG_DISABLE_AUTO_CONFIG # include #endif // #ifndef SPROUT_CONFIG_DISABLE_AUTO_CONFIG -#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR -# define SPROUT_CONSTEXPR constexpr -# define SPROUT_CONSTEXPR_OR_CONST constexpr -# define SPROUT_STATIC_CONSTEXPR static constexpr -# -# define SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER(EXPR) = EXPR -# define SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(EXPR) -#else // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR -# define SPROUT_CONSTEXPR -# define SPROUT_CONSTEXPR_OR_CONST const -# define SPROUT_STATIC_CONSTEXPR static const -# -# define SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER(EXPR) -# define SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(EXPR) = EXPR -#endif // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR - -#ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT -# define SPROUT_NOEXCEPT noexcept -# define SPROUT_NOEXCEPT_EXPR(EXPR) noexcept(EXPR) -# define SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(EXPR, C) noexcept(EXPR) -#else // #ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT -# define SPROUT_NOEXCEPT -# define SPROUT_NOEXCEPT_EXPR(EXPR) -# define SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(EXPR, C) C -#endif // #ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT - -#ifndef SPROUT_CONFIG_DISABLE_TEMPLATE_ALIASES -# define SPROUT_USE_TEMPLATE_ALIASES 1 -#else // #ifndef SPROUT_CONFIG_DISABLE_TEMPLATE_ALIASES -# define SPROUT_USE_TEMPLATE_ALIASES 0 -#endif // #ifndef SPROUT_CONFIG_DISABLE_TEMPLATE_ALIASES - -#ifndef SPROUT_CONFIG_DISABLE_USER_DEFINED_LITERALS -# define SPROUT_USE_USER_DEFINED_LITERALS 1 -#else // #ifndef SPROUT_CONFIG_DISABLE_USER_DEFINED_LITERALS -# define SPROUT_USE_USER_DEFINED_LITERALS 0 -#endif // #ifndef SPROUT_CONFIG_DISABLE_USER_DEFINED_LITERALS - -#ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS -# define SPROUT_USE_DELEGATING_CONSTRUCTORS 1 -#else // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS -# define SPROUT_USE_DELEGATING_CONSTRUCTORS 0 -#endif // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS - -#ifndef SPROUT_CONFIG_USE_SSCRISK_CEL -# define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT -# define HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT -# define HDR_NUMERIC_SSCRISK_CEL_OR_SPROUT -# define HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT -# define NS_SSCRISK_CEL_OR_SPROUT sprout -#else // #ifndef SPROUT_CONFIG_USE_SSCRISK_CEL -# define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT -# define HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT -# define HDR_NUMERIC_SSCRISK_CEL_OR_SPROUT -# define HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT -# define NS_SSCRISK_CEL_OR_SPROUT sscrisk::cel -#endif // #ifndef SPROUT_CONFIG_USE_SSCRISK_CEL - -#ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION -# define SPROUT_USE_BUILTIN_CMATH_FUNCTION 1 -#else // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION -# define SPROUT_USE_BUILTIN_CMATH_FUNCTION 0 -#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION - -#ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION -# define SPROUT_USE_BUILTIN_BIT_OPERATION 1 -#else // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION -# define SPROUT_USE_BUILTIN_BIT_OPERATION 0 -#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION - -#ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION -# define SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION 1 -#else // #ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION -# ifdef SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION -# error config conflict: SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION, SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION -# endif // #ifndef SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION -# define SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION 0 -#endif // #ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION +#include +#include #endif // #ifndef SPROUT_CONFIG_CONFIG_HPP diff --git a/sprout/config/suffix.hpp b/sprout/config/suffix.hpp new file mode 100644 index 00000000..460be48d --- /dev/null +++ b/sprout/config/suffix.hpp @@ -0,0 +1,83 @@ +#ifndef SPROUT_CONFIG_SUFFIX_HPP +#define SPROUT_CONFIG_SUFFIX_HPP + +#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR +# define SPROUT_CONSTEXPR constexpr +# define SPROUT_CONSTEXPR_OR_CONST constexpr +# define SPROUT_STATIC_CONSTEXPR static constexpr +# +# define SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER(EXPR) = EXPR +# define SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(EXPR) +#else // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR +# define SPROUT_CONSTEXPR +# define SPROUT_CONSTEXPR_OR_CONST const +# define SPROUT_STATIC_CONSTEXPR static const +# +# define SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER(EXPR) +# define SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(EXPR) = EXPR +#endif // #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR + +#ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT +# define SPROUT_NOEXCEPT noexcept +# define SPROUT_NOEXCEPT_EXPR(EXPR) noexcept(EXPR) +# define SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(EXPR, C) noexcept(EXPR) +#else // #ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT +# define SPROUT_NOEXCEPT +# define SPROUT_NOEXCEPT_EXPR(EXPR) +# define SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(EXPR, C) C +#endif // #ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT + +#ifndef SPROUT_CONFIG_DISABLE_TEMPLATE_ALIASES +# define SPROUT_USE_TEMPLATE_ALIASES 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_TEMPLATE_ALIASES +# define SPROUT_USE_TEMPLATE_ALIASES 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_TEMPLATE_ALIASES + +#ifndef SPROUT_CONFIG_DISABLE_USER_DEFINED_LITERALS +# define SPROUT_USE_USER_DEFINED_LITERALS 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_USER_DEFINED_LITERALS +# define SPROUT_USE_USER_DEFINED_LITERALS 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_USER_DEFINED_LITERALS + +#ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS +# define SPROUT_USE_DELEGATING_CONSTRUCTORS 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS +# define SPROUT_USE_DELEGATING_CONSTRUCTORS 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS + +#ifndef SPROUT_CONFIG_USE_SSCRISK_CEL +# define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT +# define HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT +# define HDR_NUMERIC_SSCRISK_CEL_OR_SPROUT +# define HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT +# define NS_SSCRISK_CEL_OR_SPROUT sprout +#else // #ifndef SPROUT_CONFIG_USE_SSCRISK_CEL +# define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT +# define HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT +# define HDR_NUMERIC_SSCRISK_CEL_OR_SPROUT +# define HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT +# define NS_SSCRISK_CEL_OR_SPROUT sscrisk::cel +#endif // #ifndef SPROUT_CONFIG_USE_SSCRISK_CEL + +#ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION +# define SPROUT_USE_BUILTIN_CMATH_FUNCTION 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION +# define SPROUT_USE_BUILTIN_CMATH_FUNCTION 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION + +#ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION +# define SPROUT_USE_BUILTIN_BIT_OPERATION 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION +# define SPROUT_USE_BUILTIN_BIT_OPERATION 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION + +#ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION +# define SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION +# ifdef SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION +# error config conflict: SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION, SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION +# endif // #ifndef SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION +# define SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION + +#endif // #ifndef SPROUT_CONFIG_SUFFIX_HPP diff --git a/sprout/none.hpp b/sprout/none.hpp new file mode 100644 index 00000000..3cd8fa22 --- /dev/null +++ b/sprout/none.hpp @@ -0,0 +1,17 @@ +#ifndef SPROUT_NONE_HPP +#define SPROUT_NONE_HPP + +#include + +namespace sprout { + // + // none_t + // none + // + struct none_t {}; + namespace { + SPROUT_STATIC_CONSTEXPR none_t none{}; + } // anonymous-namespace +} // namespace sprout + +#endif // #ifndef SPROUT_NONE_HPP diff --git a/sprout/optional.hpp b/sprout/optional.hpp new file mode 100644 index 00000000..b4669d6a --- /dev/null +++ b/sprout/optional.hpp @@ -0,0 +1,11 @@ +#ifndef SPROUT_OPTIONAL_HPP +#define SPROUT_OPTIONAL_HPP + +#include +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_OPTIONAL_HPP diff --git a/sprout/optional/comparison.hpp b/sprout/optional/comparison.hpp new file mode 100644 index 00000000..5bff3974 --- /dev/null +++ b/sprout/optional/comparison.hpp @@ -0,0 +1,49 @@ +#ifndef SPROUT_OPTIONAL_COMPARISON_HPP +#define SPROUT_OPTIONAL_COMPARISON_HPP + +#include +#include +#include + +namespace sprout { + // + // operator== + // operator!= + // operator< + // operator> + // operator<= + // operator>= + // + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::optional const& lhs, sprout::optional const& rhs) { + return sprout::equal_pointees(lhs, rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::optional const& lhs, sprout::optional const& rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::optional const& lhs, sprout::optional const& rhs) { + return sprout::less_pointees(lhs, rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::optional const& lhs, sprout::optional const& rhs) { + return rhs < lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::optional const& lhs, sprout::optional const& rhs) { + return !(rhs < lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::optional const& lhs, sprout::optional const& rhs) { + return !(lhs < rhs); + } +} // namespace sprout + +#endif // #ifndef SPROUT_OPTIONAL_COMPARISON_HPP diff --git a/sprout/optional/get.hpp b/sprout/optional/get.hpp new file mode 100644 index 00000000..b12aa338 --- /dev/null +++ b/sprout/optional/get.hpp @@ -0,0 +1,61 @@ +#ifndef SPROUT_OPTIONAL_GET_HPP +#define SPROUT_OPTIONAL_GET_HPP + +#include +#include + +namespace sprout { + // + // get + // + template + inline SPROUT_CONSTEXPR typename sprout::optional::reference_const_type + get(sprout::optional const& x) { + return x.get(); + } + template + inline typename sprout::optional::reference_type + get(sprout::optional& x) { + return x.get(); + } + template + inline SPROUT_CONSTEXPR typename sprout::optional::pointer_const_type + get(sprout::optional const* x) { + return x->get_ptr(); + } + template + inline typename sprout::optional::pointer_type + get(sprout::optional* x) { + return x->get_ptr(); + } + + // + // get_pointer + // + template + inline SPROUT_CONSTEXPR typename sprout::optional::pointer_const_type + get_pointer(sprout::optional const& x) { + return x.get_pointer(); + } + template + inline typename sprout::optional::pointer_type + get_pointer(sprout::optional& x) { + return x.get_pointer(); + } + + // + // get_optional_value_or + // + template + inline SPROUT_CONSTEXPR typename sprout::optional::reference_const_type + get_optional_value_or(sprout::optional const& x, typename sprout::optional::reference_const_type v) { + return x.get_value_or(v); + } + template + inline typename sprout::optional::reference_type + get_optional_value_or(sprout::optional& x, typename sprout::optional::reference_type v) { + return x.get_value_or(v); + } +} // namespace sprout + +#endif // #ifndef SPROUT_OPTIONAL_GET_HPP diff --git a/sprout/optional/io.hpp b/sprout/optional/io.hpp new file mode 100644 index 00000000..a7bcb53c --- /dev/null +++ b/sprout/optional/io.hpp @@ -0,0 +1,53 @@ +#ifndef SPROUT_OPTIONAL_IO_HPP +#define SPROUT_OPTIONAL_IO_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + // + // operator>> + // + template + inline std::basic_istream& + operator<<(std::basic_istream& lhs, sprout::optional& 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::none; + return lhs; + } + } + lhs.setstate(std::ios::failbit); + } + } + return lhs; + } + // + // operator<< + // + template + inline std::basic_ostream& + operator<<(std::basic_ostream& lhs, sprout::optional const& rhs) { + if (lhs.good()) { + if (!rhs) { + lhs << "--"; + } else { + lhs << ' ' << *rhs; + } + } + return lhs; + } +} // namespace sprout + +#endif // #ifndef SPROUT_OPTIONAL_IO_HPP diff --git a/sprout/optional/make_optional.hpp b/sprout/optional/make_optional.hpp new file mode 100644 index 00000000..a83af000 --- /dev/null +++ b/sprout/optional/make_optional.hpp @@ -0,0 +1,23 @@ +#ifndef SPROUT_OPTIONAL_MAKE_OPTIONAL_HPP +#define SPROUT_OPTIONAL_MAKE_OPTIONAL_HPP + +#include +#include + +namespace sprout { + // + // make_optional + // + template + inline SPROUT_CONSTEXPR sprout::optional + make_optional(T const& v) { + return optional(v); + } + template + inline SPROUT_CONSTEXPR sprout::optional + make_optional(bool cond, T const& v) { + return optional(cond, v); + } +} // namespace sprout + +#endif // #ifndef SPROUT_OPTIONAL_MAKE_OPTIONAL_HPP diff --git a/sprout/optional/optional.hpp b/sprout/optional/optional.hpp new file mode 100644 index 00000000..cf6fe65b --- /dev/null +++ b/sprout/optional/optional.hpp @@ -0,0 +1,187 @@ +#ifndef SPROUT_OPTIONAL_OPTIONAL_HPP +#define SPROUT_OPTIONAL_OPTIONAL_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + // + // optional + // + template + class optional { + public: + typedef T type; + private: + typedef sprout::value_holder holder_type; + public: + typedef typename holder_type::value_type value_type; + typedef typename holder_type::reference reference; + typedef typename holder_type::const_reference const_reference; + typedef typename holder_type::pointer pointer; + typedef typename holder_type::const_pointer const_pointer; + typedef typename holder_type::reference_type reference_type; + typedef typename holder_type::reference_const_type reference_const_type; + typedef typename holder_type::pointer_type pointer_type; + typedef typename holder_type::pointer_const_type pointer_const_type; + typedef typename holder_type::argument_type argument_type; + private: + bool initialized_; + holder_type storage_; + private: + void destroy() { + initialized_ = false; + } + public: + SPROUT_CONSTEXPR optional() + : initialized_(false) + {} + SPROUT_CONSTEXPR optional(sprout::none_t) + : initialized_(false) + {} + SPROUT_CONSTEXPR optional(argument_type v) + : initialized_(true) + , storage_(v) + {} + SPROUT_CONSTEXPR optional(bool cond, argument_type v) + : initialized_(cond) + , storage_(cond ? holder_type(v) : holder_type()) + {} + SPROUT_CONSTEXPR optional(optional const& v) + : initialized_(v.initialized_) + , storage_(v.storage_) + {} + template + explicit SPROUT_CONSTEXPR optional(optional const& v) + : initialized_(v.initialized_) + , storage_(v.storage_.get()) + {} + + optional& operator=(sprout::none_t v) { + assign(v); + return *this; + } + optional& operator=(argument_type v) { + assign(v); + return *this; + } + optional& operator=(optional const& v) { + assign(v); + return *this; + } + template + optional& operator=(optional const& v) { + assign(v); + return *this; + } + + void assign(sprout::none_t) { + destroy(); + } + void assign(argument_type v) { + optional temp(v); + temp.swap(v); + } + void assign(optional const& v) { + optional temp(v); + temp.swap(v); + } + template + void assign(optional const& v) { + optional temp(v); + temp.swap(v); + } + + void reset() { + destroy(); + } + void reset(sprout::none_t v) { + assign(v); + } + void reset(argument_type v) { + assign(v); + } + + void swap(optional& other) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(storage_, other.storage_))) + { + sprout::swap(storage_, other.storage_); + } + + SPROUT_CONSTEXPR reference_const_type get() const { + return is_initialized() ? storage_.get() + : throw std::domain_error("optional: value not initialized") + ; + } + reference_type get() { + return is_initialized() ? storage_.get() + : throw std::domain_error("optional: value not initialized") + ; + } + SPROUT_CONSTEXPR reference_const_type get_value_or(reference_const_type& v) const { + return is_initialized() ? storage_.get() + : v + ; + } + reference_type get_value_or(reference_type& v) { + return is_initialized() ? storage_.get() + : v + ; + } + + SPROUT_CONSTEXPR pointer_const_type operator->() const { + return is_initialized() ? storage_.get_pointer() + : throw std::domain_error("optional: value not initialized") + ; + } + pointer_type operator->() { + return is_initialized() ? storage_.get_pointer() + : throw std::domain_error("optional: value not initialized") + ; + } + SPROUT_CONSTEXPR pointer_const_type get_pointer() const { + return is_initialized() ? storage_.get_pointer() + : throw std::domain_error("optional: value not initialized") + ; + } + pointer_type get_pointer() { + return is_initialized() ? storage_.get_pointer() + : throw std::domain_error("optional: value not initialized") + ; + } + SPROUT_CONSTEXPR pointer_const_type get_ptr() const { + return get_pointer(); + } + pointer_type get_ptr() { + return get_pointer(); + } + + SPROUT_CONSTEXPR operator bool() const { + return is_initialized(); + } + SPROUT_CONSTEXPR bool operator!() const { + return !is_initialized(); + } + SPROUT_CONSTEXPR bool is_initialized() const { + return initialized_; + } + }; + + // + // swap + // + template + inline void + swap(sprout::optional& lhs, sprout::optional& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + +} // namespace sprout + +#endif // #ifndef SPROUT_OPTIONAL_OPTIONAL_HPP +#include \ No newline at end of file diff --git a/sprout/utility.hpp b/sprout/utility.hpp index 65a69355..56e6feda 100644 --- a/sprout/utility.hpp +++ b/sprout/utility.hpp @@ -6,8 +6,9 @@ #include #include #include -#include +#include #include +#include #include #include diff --git a/sprout/utility/compare_pointees.hpp b/sprout/utility/compare_pointees.hpp new file mode 100644 index 00000000..6c88783e --- /dev/null +++ b/sprout/utility/compare_pointees.hpp @@ -0,0 +1,51 @@ +#ifndef SPROUT_UTILITY_COMPARE_POINTEES_HPP +#define SPROUT_UTILITY_COMPARE_POINTEES_HPP + +#include +#include + +namespace sprout { + // + // equal_pointees + // + template + inline SPROUT_CONSTEXPR bool + equal_pointees(OptionalPointee const& lhs, OptionalPointee const& rhs) { + return (!lhs) != (!rhs) ? false : (!lhs ? true : (*lhs) == (*rhs)); + } + // + // less_pointees + // + template + inline SPROUT_CONSTEXPR bool + less_pointees(OptionalPointee const& lhs, OptionalPointee const& rhs) { + return !rhs ? false : (!lhs ? true : (*lhs) < (*rhs)); + } + + // + // equal_pointees_t + // + template + struct equal_pointees_t + : public sprout::binary_function + { + SPROUT_CONSTEXPR bool + operator()(OptionalPointee const& lhs, OptionalPointee const& rhs) const { + return sprout::equal_pointees(lhs, rhs) ; + } + } ; + // + // less_pointees_t + // + template + struct less_pointees_t + : public sprout::binary_function + { + SPROUT_CONSTEXPR bool + operator()(OptionalPointee const& lhs, OptionalPointee const& rhs) const { + return sprout::less_pointees(lhs, rhs) ; + } + } ; +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_COMPARE_POINTEES_HPP diff --git a/sprout/utility/value_holder.hpp b/sprout/utility/value_holder.hpp index ce2c9f21..8a1620c9 100644 --- a/sprout/utility/value_holder.hpp +++ b/sprout/utility/value_holder.hpp @@ -129,6 +129,11 @@ namespace sprout { typedef typename helper_type::const_pointer const_pointer; typedef typename helper_type::mutable_or_const_pointer mutable_or_const_pointer; typedef typename helper_type::param_type param_type; + typedef reference reference_type; + typedef const_reference reference_const_type; + typedef pointer pointer_type; + typedef const_pointer pointer_const_type; + typedef param_type argument_type; private: holder_type holder_; public: @@ -154,6 +159,12 @@ namespace sprout { SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer() const { return helper_type::ptr(holder_); } + pointer get_ptr() { + return get_pointer(); + } + SPROUT_CONSTEXPR mutable_or_const_pointer get_ptr() const { + return get_pointer(); + } }; } // namespace sprout