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 _LIBCPP_CONSTEXPR chars_format +operator~(chars_format __x) { + return chars_format(~_VSTD::__to_underlying(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_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 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 chars_format +operator^(chars_format __x, chars_format __y) { + return chars_format(_VSTD::__to_underlying(__x) ^ + _VSTD::__to_underlying(__y)); +} + +inline _LIBCPP_INLINE_VISIBILITY chars_format& operator&=(chars_format& __x, + chars_format __y) { + __x = __x & __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY chars_format& operator|=(chars_format& __x, + chars_format __y) { + __x = __x | __y; + return __x; +} + +inline _LIBCPP_INLINE_VISIBILITY 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,83 @@ +//===----------------------------------------------------------------------===// +// +// 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 in C++11. To keep the code better 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" + +void test() { + { + std::chars_format x = std::chars_format::scientific; + x |= std::chars_format::fixed; + assert(x == std::chars_format::general); + } + + { + std::chars_format x = std::chars_format::general; + x &= std::chars_format::fixed; + assert(x == std::chars_format::fixed); + } + { + std::chars_format x = std::chars_format::general; + x ^= std::chars_format::fixed; + assert(x == std::chars_format::scientific); + } +} + +constexpr bool test_constexpr() { + using chars_format_underlying_type = + std::underlying_type::type; + + assert(static_cast( + std::chars_format::scientific & + (std::chars_format::fixed | std::chars_format::hex)) == 0); + assert(static_cast( + std::chars_format::fixed & + (std::chars_format::scientific | std::chars_format::hex)) == 0); + assert(static_cast( + std::chars_format::hex & + (std::chars_format::scientific | std::chars_format::fixed)) == 0); + + assert((std::chars_format::scientific | std::chars_format::fixed) == + std::chars_format::general); + + assert(static_cast( + std::chars_format::scientific & std::chars_format::fixed) == 0); + + assert((std::chars_format::general ^ std::chars_format::fixed) == + std::chars_format::scientific); + + assert((~std::chars_format::hex & std::chars_format::general) == + std::chars_format::general); + + return true; +} + +int main(int, char**) { + test(); + assert(test_constexpr()); + static_assert(test_constexpr(), ""); + + return 0; +}