.. _program_listing_file_src_rdf4cpp_TriBool.hpp: Program Listing for File TriBool.hpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/rdf4cpp/TriBool.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef RDF4CPP_UTIL_TRIBOOL_HPP #define RDF4CPP_UTIL_TRIBOOL_HPP #include #include #include namespace rdf4cpp { struct TriBool { static TriBool const True; static TriBool const False; static TriBool const Err; private: enum struct inner_value_type : int8_t { Err = -1, False = 0, True = 1 }; inner_value_type value; [[nodiscard]] constexpr size_t into_logic_table_index() const noexcept { return static_cast>(this->value) + 1; } static constexpr std::array, 3> and_logic_table{ /* lhs \ rhs Err False True */ /* Err */ std::array{inner_value_type::Err, inner_value_type::False, inner_value_type::Err}, /* False */ std::array{inner_value_type::False, inner_value_type::False, inner_value_type::False}, /* True */ std::array{inner_value_type::Err, inner_value_type::False, inner_value_type::True}}; static constexpr std::array, 3> or_logic_table{ /* lhs \ rhs Err False True */ /* Err */ std::array{inner_value_type::Err, inner_value_type::Err, inner_value_type::True}, /* False */ std::array{inner_value_type::Err, inner_value_type::False, inner_value_type::True}, /* True */ std::array{inner_value_type::True, inner_value_type::True, inner_value_type::True}}; static constexpr std::array not_logic_table{ /* Err False True */ inner_value_type::Err, inner_value_type::True, inner_value_type::False}; constexpr TriBool(inner_value_type const value) noexcept : value{value} {} public: constexpr TriBool(bool const b) noexcept : value{static_cast>(b)} {} constexpr bool operator==(TriBool const &) const noexcept = default; constexpr bool operator!=(TriBool const &) const noexcept = default; constexpr operator bool() const noexcept { return this->value == inner_value_type::True; } friend constexpr TriBool operator!(TriBool const b) noexcept { return not_logic_table[b.into_logic_table_index()]; } friend constexpr TriBool operator&&(TriBool const l, TriBool const r) noexcept { return and_logic_table[l.into_logic_table_index()][r.into_logic_table_index()]; } friend constexpr TriBool operator&&(TriBool const l, bool const r) noexcept { return l && TriBool{r}; } friend constexpr TriBool operator&&(bool const l, TriBool const r) noexcept { return TriBool{l} && r; } friend constexpr TriBool operator||(TriBool const l, TriBool const r) noexcept { return or_logic_table[l.into_logic_table_index()][r.into_logic_table_index()]; } friend constexpr TriBool operator||(TriBool const l, bool const r) noexcept { return l || TriBool{r}; } friend constexpr TriBool operator||(bool const l, TriBool const r) noexcept { return TriBool{l} || r; } }; inline constexpr TriBool TriBool::True{TriBool::inner_value_type::True}; inline constexpr TriBool TriBool::False{TriBool::inner_value_type::False}; inline constexpr TriBool TriBool::Err{TriBool::inner_value_type::Err}; namespace util { constexpr TriBool partial_weak_ordering_eq(std::partial_ordering const l, std::weak_ordering const r) noexcept { if (l == std::partial_ordering::unordered) { return TriBool::Err; } return l == r; } } // namespace util } // namespace rdf4cpp #endif // RDF4CPP_UTIL_TRIBOOL_HPP