22 #ifndef GEARS_UTILITY_TRIBOOL_HPP
23 #define GEARS_UTILITY_TRIBOOL_HPP
26 #ifndef GEARS_NO_IOSTREAM
30 #endif // GEARS_NO_IOSTREAM
34 struct indeterminate_t {
35 constexpr indeterminate_t() {}
101 enum class state : char {
102 true_, false_, unknown
108 constexpr
tribool() noexcept: value(state::unknown) {}
113 constexpr
tribool(indeterminate_t) noexcept: value(state::unknown) {}
118 constexpr
tribool(
bool v) noexcept: value(v ? state::true_ : state::false_) {}
124 explicit constexpr
operator bool() const noexcept {
125 return value == state::true_;
134 return tri.value == state::true_;
143 return tri.value == state::false_;
152 return tri.value == state::unknown;
170 return (value == state::unknown || rhs.value == state::unknown) ?
189 return (value == state::unknown || rhs.value == state::unknown) ?
232 return is_false(lhs) || is_false(rhs) ?
tribool(
false) :
236 constexpr
tribool operator&&(
const tribool& lhs,
bool b) noexcept {
240 constexpr tribool operator&&(
bool b,
const tribool& rhs) noexcept {
241 return tribool(b) && rhs;
264 return is_true(lhs) || is_true(rhs) ?
tribool(
true) :
268 constexpr
tribool operator||(
const tribool& lhs,
bool b) noexcept {
272 constexpr tribool operator||(
bool b,
const tribool& rhs) noexcept {
273 return tribool(b) || rhs;
276 #ifndef GEARS_NO_IOSTREAM
291 template<
typename CharT>
292 constexpr
const CharT* get_default_indeterminate_name() noexcept;
295 constexpr const
char* get_default_indeterminate_name<
char>() noexcept {
296 return "indeterminate";
300 constexpr
const wchar_t* get_default_indeterminate_name<wchar_t>() noexcept {
301 return L
"indeterminate";
316 template<
typename CharT>
319 using char_type = CharT;
320 using string_type = std::basic_string<CharT>;
322 string_type name_ = get_default_indeterminate_name<CharT>();
337 constexpr string_type
name() const noexcept {
341 static std::locale::id id;
344 template<
typename CharT>
345 std::locale::id indeterminate_name<CharT>::id;
380 template<
typename CharT,
typename Traits>
381 inline auto operator<<(std::basic_ostream<CharT, Traits>& out,
const tribool& tri) -> decltype(out) {
382 if(!is_indeterminate(tri)) {
383 return out << static_cast<bool>(tri);
386 typename std::basic_ostream<CharT, Traits>::sentry sentry(out);
388 if(out.flags() & std::ios_base::boolalpha) {
390 auto&& facet = std::use_facet<indeterminate_name<CharT>>(out.getloc());
394 out << get_default_indeterminate_name<CharT>();
424 template<
typename CharT,
typename Traits>
426 if(in.flags() & std::ios_base::boolalpha) {
427 typename std::basic_istream<CharT, Traits>::sentry sentry(in);
429 auto&& loc = in.getloc();
430 auto&& numpunct_facet = std::use_facet<std::numpunct<CharT>>(loc);
431 auto&& false_name = numpunct_facet.falsename();
432 auto&& true_name = numpunct_facet.truename();
435 std::basic_string<CharT> other_name = get_default_indeterminate_name<CharT>();
436 if(std::has_facet<other_facet>(loc)) {
437 auto&& facet = std::use_facet<other_facet>(loc);
438 other_name = facet.
name();
441 std::basic_string<CharT> str;
443 if(str == false_name) {
446 else if(str == true_name) {
449 else if(str == other_name) {
453 in.setstate(std::ios_base::failbit);
463 case 0: tri =
false;
break;
464 case 1: tri =
true;
break;
467 in.setstate(std::ios_base::failbit);
475 #endif // GEARS_NO_IOSTREAM
479 #endif // GEARS_UTILITY_TRIBOOL_HPP