| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- #ifndef TRIBOOL_H
- #define TRIBOOL_H
- #include <iostream>
- namespace Tribool {
- class Tribool
- {
- public:
- struct IndeterminateType
- {
- };
- typedef bool (*IndeterminateKeywordType)(Tribool, IndeterminateType);
- public:
- Tribool();
- Tribool(bool value);
- Tribool(const IndeterminateKeywordType& value);
- explicit operator bool() const;
- Tribool operator!() const;
- Tribool operator&&(const Tribool& other) const;
- friend Tribool operator&&(const Tribool& lhs, bool rhs);
- friend Tribool operator&&(bool lhs, const Tribool& rhs);
- friend Tribool operator&&(const IndeterminateKeywordType& lhs, const Tribool& rhs);
- friend Tribool operator&&(const Tribool& lhs, const IndeterminateKeywordType& rhs);
- Tribool operator||(const Tribool& other) const;
- friend Tribool operator||(const Tribool& lhs, bool rhs);
- friend Tribool operator||(bool lhs, const Tribool& rhs);
- friend Tribool operator||(const IndeterminateKeywordType& lhs, const Tribool& rhs);
- friend Tribool operator||(const Tribool& lhs, const IndeterminateKeywordType& rhs);
- Tribool operator==(const Tribool& other) const;
- friend Tribool operator==(const Tribool& lhs, bool rhs);
- friend Tribool operator==(bool lhs, const Tribool& rhs);
- friend Tribool operator==(const IndeterminateKeywordType& lhs, const Tribool& rhs);
- friend Tribool operator==(const Tribool& lhs, const IndeterminateKeywordType& rhs);
- Tribool operator!=(const Tribool& other) const;
- friend Tribool operator!=(const Tribool& lhs, bool rhs);
- friend Tribool operator!=(bool lhs, const Tribool& rhs);
- friend Tribool operator!=(const IndeterminateKeywordType& lhs, const Tribool& rhs);
- friend Tribool operator!=(const Tribool& lhs, const IndeterminateKeywordType& rhs);
- static inline bool Indeterminate(Tribool x, Tribool::IndeterminateType = Tribool::IndeterminateType())
- {
- return x.m_value == Tribool::TriboolValue::Indeterminate;
- }
- private:
- class TriboolValue
- {
- public:
- enum type
- {
- True,
- False,
- Indeterminate
- };
- };
- private:
- TriboolValue::type m_value;
- };
- template<typename CharT, typename Traits>
- inline std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& out, Tribool x)
- {
- if (!Tribool::Indeterminate(x)) {
- out << static_cast<bool>(x);
- }
- else
- {
- typename std::basic_ostream<CharT, Traits>::sentry cerberus(out);
- if (cerberus)
- {
- if (out.flags() & std::ios_base::boolalpha)
- out << "indeterminate";
- else
- out << 2;
- }
- }
- return out;
- }
- template<typename CharT, typename Traits>
- inline std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& out, bool (*)(Tribool, Tribool::IndeterminateType))
- {
- return out << Tribool(Tribool::Indeterminate);
- }
- template<typename CharT, typename Traits>
- std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& in, Tribool& x)
- {
- if (in.flags() & std::ios_base::boolalpha)
- {
- typename std::basic_istream<CharT, Traits>::sentry cerberus(in);
- if (cerberus)
- {
- typedef std::basic_string<CharT> string_type;
- string_type falsename = "false";
- string_type truename = "true";
- string_type indeterminatename = "indeterminate";
- typename string_type::size_type pos = 0;
- bool falsename_ok = true;
- bool truename_ok = true;
- bool indeterminatename_ok = true;
- while ((falsename_ok && pos < falsename.size()) || (truename_ok && pos < truename.size()) || (indeterminatename_ok && pos < indeterminatename.size()))
- {
- typename Traits::int_type c = in.get();
- if (c == Traits::eof())
- return in;
- 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 (indeterminatename_ok && pos < indeterminatename.size())
- {
- if (Traits::eq(Traits::to_char_type(c), indeterminatename[pos]))
- matched = true;
- else
- indeterminatename_ok = false;
- }
- if (matched)
- ++pos;
- if (pos > falsename.size())
- falsename_ok = false;
- if (pos > truename.size())
- truename_ok = false;
- if (pos > indeterminatename.size())
- indeterminatename_ok = false;
- }
- if (pos == 0)
- {
- in.setstate(std::ios_base::failbit);
- }
- else
- {
- if (falsename_ok)
- x = false;
- else if (truename_ok)
- x = true;
- else if (indeterminatename_ok)
- x = Tribool::Indeterminate;
- else
- in.setstate(std::ios_base::failbit);
- }
- }
- }
- else
- {
- long value;
- if (in >> value)
- {
- switch (value)
- {
- case 0:
- x = false;
- break;
- case 1:
- x = true;
- break;
- case 2:
- x = Tribool::Indeterminate;
- break;
- default:
- in.setstate(std::ios_base::failbit);
- break;
- }
- }
- }
- return in;
- }
- } // namespace Tribool
- #endif // TRIBOOL_H
|