add logic::tribool

This commit is contained in:
bolero-MURAKAMI 2012-10-11 00:15:34 +09:00
parent 33c17736fa
commit 1ef528d204
11 changed files with 478 additions and 18 deletions

2
README
View file

@ -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/

7
sprout/logic.hpp Normal file
View file

@ -0,0 +1,7 @@
#ifndef SPROUT_LOGIC_HPP
#define SPROUT_LOGIC_HPP
#include <sprout/config.hpp>
#include <sprout/logic/tribool.hpp>
#endif // #ifndef SPROUT_LOGIC_HPP

9
sprout/logic/tribool.hpp Normal file
View file

@ -0,0 +1,9 @@
#ifndef SPROUT_LOGIC_TRIBOOL_HPP
#define SPROUT_LOGIC_TRIBOOL_HPP
#include <sprout/config.hpp>
#include <sprout/logic/tribool/tribool_fwd.hpp>
#include <sprout/logic/tribool/tribool.hpp>
#include <sprout/logic/tribool/io.hpp>
#endif // #ifndef SPROUT_LOGIC_TRIBOOL_HPP

207
sprout/logic/tribool/io.hpp Normal file
View file

@ -0,0 +1,207 @@
#ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_IO_HPP
#define SPROUT_LOGIC_TRIBOOL_TRIBOOL_IO_HPP
#include <locale>
#include <string>
#include <iosfwd>
#include <ios>
#include <sprout/config.hpp>
#include <sprout/utility/noncopyable.hpp>
#include <sprout/logic/tribool/tribool.hpp>
namespace sprout {
namespace logic {
//
// get_default_indeterminate_name
//
template<typename Char>
inline std::basic_string<Char>
get_default_indeterminate_name();
template<>
inline std::basic_string<char>
get_default_indeterminate_name<char>() {
return "indeterminate";
}
template<>
inline std::basic_string<wchar_t>
get_default_indeterminate_name<wchar_t>() {
return L"indeterminate";
}
template<>
inline std::basic_string<char16_t>
get_default_indeterminate_name<char16_t>() {
return u"indeterminate";
}
template<>
inline std::basic_string<char32_t>
get_default_indeterminate_name<char32_t>() {
return U"indeterminate";
}
//
// indeterminate_name
//
template<typename Char>
class indeterminate_name
: public std::locale::facet
, private sprout::noncopyable
{
public:
typedef Char char_type;
typedef std::basic_string<char_type> string_type;
public:
static std::locale::id id;
private:
string_type name_;
public:
indeterminate_name()
: name_(sprout::logic::get_default_indeterminate_name<char_type>())
{}
explicit indeterminate_name(string_type const& initial_name)
: name_(initial_name)
{}
string_type name() const {
return name_;
}
};
template<typename Char>
std::locale::id sprout::logic::indeterminate_name<Char>::id;
//
// operator<<
//
template<typename Char, typename Traits>
inline std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& lhs, sprout::logic::tribool rhs) {
if (!sprout::logic::indeterminate(rhs)) {
lhs << static_cast<bool>(rhs);
} else {
typename std::basic_ostream<Char, Traits>::sentry cerberus(lhs);
if (cerberus) {
if (lhs.flags() & std::ios_base::boolalpha) {
if (std::has_facet<sprout::logic::indeterminate_name<Char> >(lhs.getloc())) {
indeterminate_name<Char> const& facet
= std::use_facet<sprout::logic::indeterminate_name<Char> >(lhs.getloc())
;
lhs << facet.name();
} else {
lhs << sprout::logic::get_default_indeterminate_name<Char>();
}
} else {
lhs << 2;
}
}
}
return lhs;
}
template<typename Char, typename Traits>
inline std::basic_ostream<Char, Traits>&
operator<<(std::basic_ostream<Char, Traits>& lhs, sprout::logic::indeterminate_keyword_t) {
return lhs << sprout::logic::tribool(indeterminate);
}
//
// operator>>
//
template<typename Char, typename Traits>
inline std::basic_istream<Char, Traits>&
operator>>(std::basic_istream<Char, Traits>& lhs, sprout::logic::tribool& rhs) {
if (lhs.flags() & std::ios_base::boolalpha) {
typename std::basic_istream<Char, Traits>::sentry cerberus(lhs);
if (cerberus) {
typedef std::basic_string<Char> string_type;
const std::numpunct<Char>& numpunct_facet =
std::use_facet<std::numpunct<Char> >(lhs.getloc())
;
string_type falsename = numpunct_facet.falsename();
string_type truename = numpunct_facet.truename();
string_type othername = std::has_facet<sprout::logic::indeterminate_name<Char> >(lhs.getloc())
? std::use_facet<indeterminate_name<Char> >(lhs.getloc()).name()
: sprout::logic::get_default_indeterminate_name<Char>()
;
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

View file

@ -0,0 +1,191 @@
#ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_HPP
#define SPROUT_LOGIC_TRIBOOL_TRIBOOL_HPP
#include <sprout/config.hpp>
#include <sprout/logic/tribool/tribool_fwd.hpp>
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<bool>(!lhs) || static_cast<bool>(!rhs) ? sprout::logic::tribool(false)
: static_cast<bool>(lhs) && static_cast<bool>(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<bool>(!lhs) && static_cast<bool>(!rhs) ? sprout::logic::tribool(false)
: static_cast<bool>(lhs) || static_cast<bool>(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

View file

@ -0,0 +1,15 @@
#ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_FWD_HPP
#define SPROUT_LOGIC_TRIBOOL_TRIBOOL_FWD_HPP
#include <sprout/config.hpp>
namespace sprout {
namespace logic {
//
// tribool
//
class tribool;
} // namespace logic
} // namespace sprout
#endif // #ifndef SPROUT_LOGIC_TRIBOOL_TRIBOOL_FWD_HPP

View file

@ -0,0 +1,7 @@
#ifndef SPROUT_LOGIC_TRIBOOL_FWD_HPP
#define SPROUT_LOGIC_TRIBOOL_FWD_HPP
#include <sprout/config.hpp>
#include <sprout/logic/tribool/tribool_fwd.hpp>
#endif // #ifndef SPROUT_LOGIC_TRIBOOL_FWD_HPP

View file

@ -7,6 +7,7 @@
#include <sprout/utility/operation.hpp>
#include <sprout/utility/operation_ext.hpp>
#include <sprout/utility/enabler_if.hpp>
#include <sprout/utility/noncopyable.hpp>
#include <sprout/utility/pack.hpp>
#include <sprout/utility/value_holder.hpp>

View file

@ -0,0 +1,21 @@
#ifndef SPROUT_UTILITY_NONCOPYABLE_HPP
#define SPROUT_UTILITY_NONCOPYABLE_HPP
#include <sprout/config.hpp>
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

View file

@ -113,7 +113,8 @@ namespace sprout {
// to_string_of
//
template<typename Elem, typename Traits = sprout::char_traits<Elem> >
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, 36, Traits> to_string_of(sprout::uuids::uuid const& u) {
inline SPROUT_CONSTEXPR sprout::basic_string<Elem, 36, Traits>
to_string_of(sprout::uuids::uuid const& u) {
return sprout::basic_string<Elem, 36, Traits>{
{
sprout::uuids::detail::digits<Elem>::table[(u[0] >> 4) & 0x0F],
@ -158,26 +159,24 @@ namespace sprout {
}
//
// to_string
//
inline SPROUT_CONSTEXPR sprout::basic_string<char, 36> to_string(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<char>(u);
}
//
// to_wstring
//
inline SPROUT_CONSTEXPR sprout::basic_string<wchar_t, 36> to_wstring(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<wchar_t>(u);
}
//
// to_u16string
//
inline SPROUT_CONSTEXPR sprout::basic_string<char16_t, 36> to_u16string(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<char16_t>(u);
}
//
// to_u32string
//
inline SPROUT_CONSTEXPR sprout::basic_string<char32_t, 36> to_u32string(sprout::uuids::uuid const& u) {
inline SPROUT_CONSTEXPR sprout::basic_string<char, 36>
to_string(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<char>(u);
}
inline SPROUT_CONSTEXPR sprout::basic_string<wchar_t, 36>
to_wstring(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<wchar_t>(u);
}
inline SPROUT_CONSTEXPR sprout::basic_string<char16_t, 36>
to_u16string(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<char16_t>(u);
}
inline SPROUT_CONSTEXPR sprout::basic_string<char32_t, 36>
to_u32string(sprout::uuids::uuid const& u) {
return sprout::uuids::to_string_of<char32_t>(u);
}
} // namespace uuids

View file

@ -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)
;
}