diff --git a/libcxx/include/charconv b/libcxx/include/charconv --- a/libcxx/include/charconv +++ b/libcxx/include/charconv @@ -81,6 +81,7 @@ #include #include #include +#include #include <__debug> @@ -108,6 +109,47 @@ general = fixed | scientific }; +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator~(chars_format __x) { + return chars_format(~_VSTD::__to_underlying(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator&(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) & + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator|(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) | + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format +operator^(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) ^ + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format& +operator&=(chars_format& __x, chars_format __y) { + __x = __x & __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format& +operator|=(chars_format& __x, chars_format __y) { + __x = __x | __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 chars_format& +operator^=(chars_format& __x, chars_format __y) { + __x = __x ^ __y; + return __x; +} + struct _LIBCPP_TYPE_VIS to_chars_result { char* ptr; diff --git a/libcxx/test/std/utilities/charconv/charconv.syn/chars_format.pass.cpp b/libcxx/test/std/utilities/charconv/charconv.syn/chars_format.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/charconv/charconv.syn/chars_format.pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// Note: chars_format is a C++17 feature backported to C++11. Assert isn't +// allowed in a constexpr function in C++11. To keep the code readable, C++11 +// support is untested. +// UNSUPPORTED: c++03, c++11 + +// + +// Bitmask type +// enum class chars_format { +// scientific = unspecified, +// fixed = unspecified, +// hex = unspecified, +// general = fixed | scientific +// }; + +#include +#include + +#include "test_macros.h" + +constexpr bool test() { + using cf = std::chars_format; + using ut = std::underlying_type::type; + + { + cf x = cf::scientific; + x |= cf::fixed; + assert(x == cf::general); + } + { + cf x = cf::general; + x &= cf::fixed; + assert(x == cf::fixed); + } + { + cf x = cf::general; + x ^= cf::fixed; + assert(x == cf::scientific); + } + + assert(static_cast(cf::scientific & (cf::fixed | cf::hex)) == 0); + assert(static_cast(cf::fixed & (cf::scientific | cf::hex)) == 0); + assert(static_cast(cf::hex & (cf::scientific | cf::fixed)) == 0); + + assert((cf::scientific | cf::fixed) == cf::general); + + assert(static_cast(cf::scientific & cf::fixed) == 0); + + assert((cf::general ^ cf::fixed) == cf::scientific); + + assert((~cf::hex & cf::general) == cf::general); + + return true; +} + +std::chars_format x; +static_assert(std::is_same::value, ""); +static_assert(std::is_same::value, ""); +static_assert(std::is_same::value, ""); +static_assert(std::is_same::value, ""); +static_assert(std::is_same::value, ""); +static_assert(std::is_same::value, ""); +static_assert(std::is_same::value, ""); + +int main(int, char**) { + assert(test()); + static_assert(test(), ""); + + return 0; +}