/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #pragma once #include "cmConfigure.h" // IWYU pragma: keep #include #include #include class cmValue { public: cmValue() noexcept = default; cmValue(std::nullptr_t) noexcept {} explicit cmValue(const std::string* value) noexcept : Value(value) { } explicit cmValue(const std::string& value) noexcept : Value(&value) { } cmValue(const cmValue& other) noexcept = default; cmValue& operator=(const cmValue& other) noexcept = default; cmValue& operator=(std::nullptr_t) noexcept { this->Value = nullptr; return *this; } const std::string* Get() const noexcept { return this->Value; } const char* GetCStr() const noexcept { return this->Value ? this->Value->c_str() : nullptr; } const std::string* operator->() const noexcept { return this->Value ? this->Value : &cmValue::Empty; } const std::string& operator*() const noexcept { return this->Value ? *this->Value : cmValue::Empty; } explicit operator bool() const noexcept { return this->Value != nullptr; } operator const std::string&() const noexcept { return this->operator*(); } explicit operator cm::string_view() const noexcept { return this->operator*(); } /** * Does the value indicate a true or ON value? */ bool IsOn() const noexcept { return this->Value && cmValue::IsOn(cm::string_view(*this->Value)); } /** * Does the value indicate a false or off value ? Note that this is * not the same as !IsOn(...) because there are a number of * ambiguous values such as "/usr/local/bin" a path will result in * IsOn and IsOff both returning false. Note that the special path * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true. */ bool IsOff() const noexcept { return !this->Value || cmValue::IsOff(cm::string_view(*this->Value)); } /** Return true if value is NOTFOUND or ends in -NOTFOUND. */ bool IsNOTFOUND() const noexcept { return this->Value && cmValue::IsNOTFOUND(cm::string_view(*this->Value)); } bool IsEmpty() const noexcept { return !this->Value || this->Value->empty(); } /** * Does a string indicates that CMake/CPack/CTest internally * forced this value. This is not the same as On, but this * may be considered as "internally switched on". */ bool IsInternallyOn() const noexcept { return this->Value && cmValue::IsInternallyOn(cm::string_view(*this->Value)); } bool IsSet() const noexcept { return !this->IsEmpty() && !this->IsNOTFOUND(); } /** * Does a string indicate a true or ON value? */ static bool IsOn(const char* value) noexcept { return value && IsOn(cm::string_view(value)); } static bool IsOn(cm::string_view) noexcept; /** * Compare method has same semantic as std::optional::compare */ int Compare(cmValue value) const noexcept; int Compare(cm::string_view value) const noexcept; /** * Does a string indicate a false or off value ? Note that this is * not the same as !IsOn(...) because there are a number of * ambiguous values such as "/usr/local/bin" a path will result in * IsOn and IsOff both returning false. Note that the special path * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true. */ static bool IsOff(const char* value) noexcept { return !value || IsOff(cm::string_view(value)); } static bool IsOff(cm::string_view) noexcept; /** Return true if value is NOTFOUND or ends in -NOTFOUND. */ static bool IsNOTFOUND(const char* value) noexcept { return !value || IsNOTFOUND(cm::string_view(value)); } static bool IsNOTFOUND(cm::string_view) noexcept; static bool IsEmpty(const char* value) noexcept { return !value || *value == '\0'; } static bool IsEmpty(cm::string_view value) noexcept { return value.empty(); } /** * Does a string indicates that CMake/CPack/CTest internally * forced this value. This is not the same as On, but this * may be considered as "internally switched on". */ static bool IsInternallyOn(const char* value) noexcept { return value && IsInternallyOn(cm::string_view(value)); } static bool IsInternallyOn(cm::string_view) noexcept; private: static std::string Empty; const std::string* Value = nullptr; }; std::ostream& operator<<(std::ostream& o, cmValue v); inline bool operator==(cmValue l, cmValue r) noexcept { return l.Compare(r) == 0; } inline bool operator!=(cmValue l, cmValue r) noexcept { return l.Compare(r) != 0; } inline bool operator<(cmValue l, cmValue r) noexcept { return l.Compare(r) < 0; } inline bool operator<=(cmValue l, cmValue r) noexcept { return l.Compare(r) <= 0; } inline bool operator>(cmValue l, cmValue r) noexcept { return l.Compare(r) > 0; } inline bool operator>=(cmValue l, cmValue r) noexcept { return l.Compare(r) >= 0; } inline bool operator==(cmValue l, cm::string_view r) noexcept { return l.Compare(r) == 0; } inline bool operator!=(cmValue l, cm::string_view r) noexcept { return l.Compare(r) != 0; } inline bool operator<(cmValue l, cm::string_view r) noexcept { return l.Compare(r) < 0; } inline bool operator<=(cmValue l, cm::string_view r) noexcept { return l.Compare(r) <= 0; } inline bool operator>(cmValue l, cm::string_view r) noexcept { return l.Compare(r) > 0; } inline bool operator>=(cmValue l, cm::string_view r) noexcept { return l.Compare(r) >= 0; } inline bool operator==(cmValue l, std::nullptr_t) noexcept { return l.Compare(cmValue{}) == 0; } inline bool operator!=(cmValue l, std::nullptr_t) noexcept { return l.Compare(cmValue{}) != 0; } inline bool operator<(cmValue l, std::nullptr_t) noexcept { return l.Compare(cmValue{}) < 0; } inline bool operator<=(cmValue l, std::nullptr_t) noexcept { return l.Compare(cmValue{}) <= 0; } inline bool operator>(cmValue l, std::nullptr_t) noexcept { return l.Compare(cmValue{}) > 0; } inline bool operator>=(cmValue l, std::nullptr_t) noexcept { return l.Compare(cmValue{}) >= 0; } /** * Does a string indicate a true or ON value? This is not the same as ifdef. */ inline bool cmIsOn(cm::string_view val) { return cmValue::IsOn(val); } inline bool cmIsOn(const char* val) { return cmValue::IsOn(val); } inline bool cmIsOn(cmValue val) { return val.IsOn(); } /** * Does a string indicate a false or off value ? Note that this is * not the same as !IsOn(...) because there are a number of * ambiguous values such as "/usr/local/bin" a path will result in * IsON and IsOff both returning false. Note that the special path * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true. */ inline bool cmIsOff(cm::string_view val) { return cmValue::IsOff(val); } inline bool cmIsOff(const char* val) { return cmValue::IsOff(val); } inline bool cmIsOff(cmValue val) { return val.IsOff(); } /** Return true if value is NOTFOUND or ends in -NOTFOUND. */ inline bool cmIsNOTFOUND(cm::string_view val) { return cmValue::IsNOTFOUND(val); } inline bool cmIsNOTFOUND(cmValue val) { return val.IsNOTFOUND(); } /** Check for non-empty Property/Variable value. */ inline bool cmNonempty(cm::string_view val) { return !cmValue::IsEmpty(val); } inline bool cmNonempty(const char* val) { return !cmValue::IsEmpty(val); } inline bool cmNonempty(cmValue val) { return !val.IsEmpty(); } /** * Does a string indicates that CMake/CPack/CTest internally * forced this value. This is not the same as On, but this * may be considered as "internally switched on". */ inline bool cmIsInternallyOn(cm::string_view val) { return cmValue::IsInternallyOn(val); } inline bool cmIsInternallyOn(const char* val) { return cmValue::IsInternallyOn(val); } inline bool cmIsInternallyOn(cmValue val) { return val.IsInternallyOn(); }