Initial commit
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
#ifndef TRIBOOL_H
|
||||
#define TRIBOOL_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace Utilities {
|
||||
|
||||
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 Utilities
|
||||
|
||||
#endif // TRIBOOL_H
|
||||
Reference in New Issue
Block a user