From 1ef528d2045302f825df75ef53c2c8ff1d068fe0 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 11 Oct 2012 00:15:34 +0900 Subject: [PATCH] add logic::tribool --- README | 2 + sprout/logic.hpp | 7 + sprout/logic/tribool.hpp | 9 ++ sprout/logic/tribool/io.hpp | 207 +++++++++++++++++++++++++++ sprout/logic/tribool/tribool.hpp | 191 ++++++++++++++++++++++++ sprout/logic/tribool/tribool_fwd.hpp | 15 ++ sprout/logic/tribool_fwd.hpp | 7 + sprout/utility.hpp | 1 + sprout/utility/noncopyable.hpp | 21 +++ sprout/uuid/io.hpp | 33 +++-- testspr/tools.hpp | 3 +- 11 files changed, 478 insertions(+), 18 deletions(-) create mode 100644 sprout/logic.hpp create mode 100644 sprout/logic/tribool.hpp create mode 100644 sprout/logic/tribool/io.hpp create mode 100644 sprout/logic/tribool/tribool.hpp create mode 100644 sprout/logic/tribool/tribool_fwd.hpp create mode 100644 sprout/logic/tribool_fwd.hpp create mode 100644 sprout/utility/noncopyable.hpp diff --git a/README b/README index 9f9748ca..55ec6e98 100644 --- a/README +++ b/README @@ -167,6 +167,8 @@ https://github.com/sscrisk/CEL---ConstExpr-Library * 作者 (Author) Bolero MURAKAMI + +Website: http://www.boleros.x0.com/ Twitter: https://twitter.com/bolero_murakami Facebook: http://www.facebook.com/genya.murakami Blog: http://d.hatena.ne.jp/boleros/ diff --git a/sprout/logic.hpp b/sprout/logic.hpp new file mode 100644 index 00000000..6224a4cc --- /dev/null +++ b/sprout/logic.hpp @@ -0,0 +1,7 @@ +#ifndef SPROUT_LOGIC_HPP +#define SPROUT_LOGIC_HPP + +#include +#include + +#endif // #ifndef SPROUT_LOGIC_HPP diff --git a/sprout/logic/tribool.hpp b/sprout/logic/tribool.hpp new file mode 100644 index 00000000..56894b26 --- /dev/null +++ b/sprout/logic/tribool.hpp @@ -0,0 +1,9 @@ +#ifndef SPROUT_LOGIC_TRIBOOL_HPP +#define SPROUT_LOGIC_TRIBOOL_HPP + +#include +#include +#include +#include + +#endif // #ifndef SPROUT_LOGIC_TRIBOOL_HPP diff --git a/sprout/logic/tribool/io.hpp b/sprout/logic/tribool/io.hpp new file mode 100644 index 00000000..f249e39b --- /dev/null +++ b/sprout/logic/tribool/io.hpp @@ -0,0 +1,207 @@ +#ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_IO_HPP +#define SPROUT_LOGIC_TRIBOOL_TRIBOOL_IO_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace logic { + // + // get_default_indeterminate_name + // + template + inline std::basic_string + get_default_indeterminate_name(); + template<> + inline std::basic_string + get_default_indeterminate_name() { + return "indeterminate"; + } + template<> + inline std::basic_string + get_default_indeterminate_name() { + return L"indeterminate"; + } + template<> + inline std::basic_string + get_default_indeterminate_name() { + return u"indeterminate"; + } + template<> + inline std::basic_string + get_default_indeterminate_name() { + return U"indeterminate"; + } + + // + // indeterminate_name + // + template + class indeterminate_name + : public std::locale::facet + , private sprout::noncopyable + { + public: + typedef Char char_type; + typedef std::basic_string string_type; + public: + static std::locale::id id; + private: + string_type name_; + public: + indeterminate_name() + : name_(sprout::logic::get_default_indeterminate_name()) + {} + explicit indeterminate_name(string_type const& initial_name) + : name_(initial_name) + {} + string_type name() const { + return name_; + } + }; + template + std::locale::id sprout::logic::indeterminate_name::id; + + // + // operator<< + // + template + inline std::basic_ostream& + operator<<(std::basic_ostream& lhs, sprout::logic::tribool rhs) { + if (!sprout::logic::indeterminate(rhs)) { + lhs << static_cast(rhs); + } else { + typename std::basic_ostream::sentry cerberus(lhs); + if (cerberus) { + if (lhs.flags() & std::ios_base::boolalpha) { + if (std::has_facet >(lhs.getloc())) { + indeterminate_name const& facet + = std::use_facet >(lhs.getloc()) + ; + lhs << facet.name(); + } else { + lhs << sprout::logic::get_default_indeterminate_name(); + } + } else { + lhs << 2; + } + } + } + return lhs; + } + template + inline std::basic_ostream& + operator<<(std::basic_ostream& lhs, sprout::logic::indeterminate_keyword_t) { + return lhs << sprout::logic::tribool(indeterminate); + } + + // + // operator>> + // + template + inline std::basic_istream& + operator>>(std::basic_istream& lhs, sprout::logic::tribool& rhs) { + if (lhs.flags() & std::ios_base::boolalpha) { + typename std::basic_istream::sentry cerberus(lhs); + if (cerberus) { + typedef std::basic_string string_type; + const std::numpunct& numpunct_facet = + std::use_facet >(lhs.getloc()) + ; + string_type falsename = numpunct_facet.falsename(); + string_type truename = numpunct_facet.truename(); + string_type othername = std::has_facet >(lhs.getloc()) + ? std::use_facet >(lhs.getloc()).name() + : sprout::logic::get_default_indeterminate_name() + ; + typename string_type::size_type pos = 0; + bool falsename_ok = true; + bool truename_ok = true; + bool othername_ok = true; + while (falsename_ok && pos < falsename.size() + || truename_ok && pos < truename.size() + || othername_ok && pos < othername.size() + ) + { + typename Traits::int_type c = lhs.get(); + if (c == Traits::eof()) { + return lhs; + } + bool matched = false; + if (falsename_ok && pos < falsename.size()) { + if (Traits::eq(Traits::to_char_type(c), falsename[pos])) { + matched = true; + } else { + falsename_ok = false; + } + } + if (truename_ok && pos < truename.size()) { + if (Traits::eq(Traits::to_char_type(c), truename[pos])) { + matched = true; + } else { + truename_ok = false; + } + } + if (othername_ok && pos < othername.size()) { + if (Traits::eq(Traits::to_char_type(c), othername[pos])) { + matched = true; + } else { + othername_ok = false; + } + } + if (matched) { + ++pos; + } + if (pos > falsename.size()) { + falsename_ok = false; + } + if (pos > truename.size()) { + truename_ok = false; + } + if (pos > othername.size()) { + othername_ok = false; + } + } + if (pos == 0) { + lhs.setstate(std::ios_base::failbit); + } else { + if (falsename_ok) { + rhs = false; + } else if (truename_ok) { + rhs = true; + } else if (othername_ok) { + rhs = indeterminate; + } else { + lhs.setstate(std::ios_base::failbit); + } + } + } + } else { + long value; + if (lhs >> value) { + switch (value) { + case 0: + rhs = false; + break; + case 1: + rhs = true; + break; + case 2: + rhs = indeterminate; + break; + default: + lhs.setstate(std::ios_base::failbit); + } + } + } + return lhs; + } + } // namespace logic +} // namespace sprout + +#endif // #ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_IO_HPP diff --git a/sprout/logic/tribool/tribool.hpp b/sprout/logic/tribool/tribool.hpp new file mode 100644 index 00000000..48830a7c --- /dev/null +++ b/sprout/logic/tribool/tribool.hpp @@ -0,0 +1,191 @@ +#ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_HPP +#define SPROUT_LOGIC_TRIBOOL_TRIBOOL_HPP + +#include +#include + +namespace sprout { + namespace logic { + namespace detail { + struct indeterminate_t {}; + } // namespace detail + + // + // indeterminate_keyword_t + // + typedef bool (*indeterminate_keyword_t)(sprout::logic::tribool, sprout::logic::detail::indeterminate_t); + + // + // tribool + // + class tribool { + private: + struct dummy { + public: + void nonnull() {} + }; + typedef void (dummy::*safe_bool)(); + public: + enum value_t { + false_value, + true_value, + indeterminate_value + }; + public: + value_t value; + public: + SPROUT_CONSTEXPR tribool() + : value(false_value) + {} + SPROUT_CONSTEXPR tribool(bool initial_value) + : value(initial_value? true_value : false_value) + {} + SPROUT_CONSTEXPR tribool(sprout::logic::indeterminate_keyword_t) + : value(indeterminate_value) + {} + SPROUT_CONSTEXPR operator safe_bool() const { + return value == true_value ? &dummy::nonnull : 0; + } + }; + + // + // indeterminate + // + inline SPROUT_CONSTEXPR bool + indeterminate(sprout::logic::tribool x, sprout::logic::detail::indeterminate_t = sprout::logic::detail::indeterminate_t()) { + return x.value == sprout::logic::tribool::indeterminate_value; + } + + // + // operator! + // + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator!(sprout::logic::tribool x) { + return x.value == sprout::logic::tribool::false_value ? sprout::logic::tribool(true) + : x.value == sprout::logic::tribool::true_value ? sprout::logic::tribool(false) + : sprout::logic::tribool(sprout::logic::indeterminate) + ; + } + + // + // operator&& + // + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator&&(sprout::logic::tribool lhs, sprout::logic::tribool rhs) { + return static_cast(!lhs) || static_cast(!rhs) ? sprout::logic::tribool(false) + : static_cast(lhs) && static_cast(rhs) ? sprout::logic::tribool(true) + : sprout::logic::tribool(sprout::logic::indeterminate) + ; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator&&(tribool lhs, bool rhs) { + return rhs ? lhs : sprout::logic::tribool(false); + } + + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator&&(bool lhs, sprout::logic::tribool rhs) { + return lhs ? rhs : sprout::logic::tribool(false); + } + + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator&&(sprout::logic::indeterminate_keyword_t, sprout::logic::tribool lhs) { + return !lhs ? sprout::logic::tribool(false) : sprout::logic::tribool(sprout::logic::indeterminate); + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator&&(sprout::logic::tribool lhs, sprout::logic::indeterminate_keyword_t) { + return !lhs ? sprout::logic::tribool(false) : sprout::logic::tribool(indeterminate); + } + + // + // operator|| + // + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator||(sprout::logic::tribool lhs, sprout::logic::tribool rhs) { + return static_cast(!lhs) && static_cast(!rhs) ? sprout::logic::tribool(false) + : static_cast(lhs) || static_cast(rhs) ? sprout::logic::tribool(true) + : sprout::logic::tribool(sprout::logic::indeterminate) + ; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator||(sprout::logic::tribool lhs, bool rhs) { + return rhs ? sprout::logic::tribool(true) : lhs; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator||(bool lhs, sprout::logic::tribool rhs) { + return lhs ? sprout::logic::tribool(true) : rhs; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator||(sprout::logic::indeterminate_keyword_t, sprout::logic::tribool lhs) { + return lhs ? sprout::logic::tribool(true) : sprout::logic::tribool(sprout::logic::indeterminate); + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator||(sprout::logic::tribool lhs, sprout::logic::indeterminate_keyword_t) { + return lhs ? sprout::logic::tribool(true) : sprout::logic::tribool(sprout::logic::indeterminate); + } + + // + // operator== + // + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator==(sprout::logic::tribool lhs, sprout::logic::tribool rhs) { + return sprout::logic::indeterminate(lhs) || sprout::logic::indeterminate(rhs) + ? sprout::logic::tribool(sprout::logic::indeterminate) + : (lhs && rhs) || (!lhs && !rhs) + ; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator==(sprout::logic::tribool lhs, bool rhs) { + return lhs == sprout::logic::tribool(rhs); + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator==(bool lhs, sprout::logic::tribool rhs) { + return sprout::logic::tribool(lhs) == rhs; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator==(sprout::logic::indeterminate_keyword_t, sprout::logic::tribool lhs) { + return sprout::logic::tribool(sprout::logic::indeterminate) == lhs; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator==(sprout::logic::tribool lhs, sprout::logic::indeterminate_keyword_t) { + return sprout::logic::tribool(sprout::logic::indeterminate) == lhs; + } + + // + // operator!= + // + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator!=(sprout::logic::tribool lhs, sprout::logic::tribool rhs) { + return sprout::logic::indeterminate(lhs) || sprout::logic::indeterminate(rhs) + ? sprout::logic::tribool(sprout::logic::indeterminate) + : !((lhs && rhs) || (!lhs && !rhs)) + ; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator!=(sprout::logic::tribool lhs, bool rhs) { + return lhs != sprout::logic::tribool(rhs); + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator!=(bool lhs, sprout::logic::tribool rhs) { + return sprout::logic::tribool(lhs) != rhs; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator!=(sprout::logic::indeterminate_keyword_t, sprout::logic::tribool lhs) { + return sprout::logic::tribool(sprout::logic::indeterminate) != lhs; + } + inline SPROUT_CONSTEXPR sprout::logic::tribool + operator!=(sprout::logic::tribool lhs, sprout::logic::indeterminate_keyword_t) { + return sprout::logic::tribool(sprout::logic::indeterminate) != lhs; + } + } // namespace logic + + using sprout::logic::tribool; + using sprout::logic::indeterminate; +} // namespace sprout + +#define SPROUT_TRIBOOL_THIRD_STATE(NAME) \ + inline SPROUT_CONSTEXPR bool \ + NAME(sprout::logic::tribool lhs, sprout::logic::detail::indeterminate_t = sprout::logic::detail::indeterminate_t()) { \ + return lhs.value == sprout::logic::tribool::indeterminate_value; \ + } + +#endif // #ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_HPP diff --git a/sprout/logic/tribool/tribool_fwd.hpp b/sprout/logic/tribool/tribool_fwd.hpp new file mode 100644 index 00000000..6f518e3e --- /dev/null +++ b/sprout/logic/tribool/tribool_fwd.hpp @@ -0,0 +1,15 @@ +#ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_FWD_HPP +#define SPROUT_LOGIC_TRIBOOL_TRIBOOL_FWD_HPP + +#include + +namespace sprout { + namespace logic { + // + // tribool + // + class tribool; + } // namespace logic +} // namespace sprout + +#endif // #ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_FWD_HPP diff --git a/sprout/logic/tribool_fwd.hpp b/sprout/logic/tribool_fwd.hpp new file mode 100644 index 00000000..e6bc719c --- /dev/null +++ b/sprout/logic/tribool_fwd.hpp @@ -0,0 +1,7 @@ +#ifndef SPROUT_LOGIC_TRIBOOL_FWD_HPP +#define SPROUT_LOGIC_TRIBOOL_FWD_HPP + +#include +#include + +#endif // #ifndef SPROUT_LOGIC_TRIBOOL_FWD_HPP diff --git a/sprout/utility.hpp b/sprout/utility.hpp index 3734ae6f..65a69355 100644 --- a/sprout/utility.hpp +++ b/sprout/utility.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/sprout/utility/noncopyable.hpp b/sprout/utility/noncopyable.hpp new file mode 100644 index 00000000..7c039870 --- /dev/null +++ b/sprout/utility/noncopyable.hpp @@ -0,0 +1,21 @@ +#ifndef SPROUT_UTILITY_NONCOPYABLE_HPP +#define SPROUT_UTILITY_NONCOPYABLE_HPP + +#include + +namespace sprout { + namespace noncopyable_ { + class noncopyable { + public: + SPROUT_CONSTEXPR noncopyable() = default; + noncopyable(noncopyable const&) = delete; + noncopyable& operator=(noncopyable const&) = delete; + }; + } // namespace noncopyable_ + // + // noncopyable + // + typedef sprout::noncopyable_::noncopyable noncopyable; +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_NONCOPYABLE_HPP diff --git a/sprout/uuid/io.hpp b/sprout/uuid/io.hpp index b743765a..9077a772 100644 --- a/sprout/uuid/io.hpp +++ b/sprout/uuid/io.hpp @@ -113,7 +113,8 @@ namespace sprout { // to_string_of // template > - inline SPROUT_CONSTEXPR sprout::basic_string to_string_of(sprout::uuids::uuid const& u) { + inline SPROUT_CONSTEXPR sprout::basic_string + to_string_of(sprout::uuids::uuid const& u) { return sprout::basic_string{ { sprout::uuids::detail::digits::table[(u[0] >> 4) & 0x0F], @@ -158,26 +159,24 @@ namespace sprout { } // // to_string - // - inline SPROUT_CONSTEXPR sprout::basic_string to_string(sprout::uuids::uuid const& u) { - return sprout::uuids::to_string_of(u); - } - // // to_wstring - // - inline SPROUT_CONSTEXPR sprout::basic_string to_wstring(sprout::uuids::uuid const& u) { - return sprout::uuids::to_string_of(u); - } - // // to_u16string - // - inline SPROUT_CONSTEXPR sprout::basic_string to_u16string(sprout::uuids::uuid const& u) { - return sprout::uuids::to_string_of(u); - } - // // to_u32string // - inline SPROUT_CONSTEXPR sprout::basic_string to_u32string(sprout::uuids::uuid const& u) { + inline SPROUT_CONSTEXPR sprout::basic_string + to_string(sprout::uuids::uuid const& u) { + return sprout::uuids::to_string_of(u); + } + inline SPROUT_CONSTEXPR sprout::basic_string + to_wstring(sprout::uuids::uuid const& u) { + return sprout::uuids::to_string_of(u); + } + inline SPROUT_CONSTEXPR sprout::basic_string + to_u16string(sprout::uuids::uuid const& u) { + return sprout::uuids::to_string_of(u); + } + inline SPROUT_CONSTEXPR sprout::basic_string + to_u32string(sprout::uuids::uuid const& u) { return sprout::uuids::to_string_of(u); } } // namespace uuids diff --git a/testspr/tools.hpp b/testspr/tools.hpp index 60056458..98a960cd 100644 --- a/testspr/tools.hpp +++ b/testspr/tools.hpp @@ -265,7 +265,8 @@ namespace testspr { ) { return first1_ == last1 && first2_ == last2 ? true - : testspr::count(first1, last1, *first1_) != testspr::count(first2, first2 + testspr::distance(first1, last1), *first1_) ? false + : testspr::count(first1, last1, *first1_) != testspr::count(first2, first2 + testspr::distance(first1, last1), *first1_) + ? false : testspr::detail::is_permutation_impl(first1, last1, first2, last2, first1_ + 1, first2_ + 1) ; }