| 1 | //===----------------------------------------------------------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #ifndef TEST_STD_CONTAINERS_SEQUENCES_VECTOR_BOOL_VECTOR_BOOL_FMT_FORMAT_FUNCTIONS_TESTS_H |
| 10 | #define TEST_STD_CONTAINERS_SEQUENCES_VECTOR_BOOL_VECTOR_BOOL_FMT_FORMAT_FUNCTIONS_TESTS_H |
| 11 | |
| 12 | #include <vector> |
| 13 | |
| 14 | #include "format.functions.common.h" |
| 15 | #include "test_macros.h" |
| 16 | |
| 17 | template <class CharT, class TestFunction, class ExceptionTest> |
| 18 | void format_test_vector_bool(TestFunction check, ExceptionTest check_exception, auto&& input) { |
| 19 | check(SV("[true, true, false]" ), SV("{}" ), input); |
| 20 | check(SV("[true, true, false]^42" ), SV("{}^42" ), input); |
| 21 | check(SV("[true, true, false]^42" ), SV("{:}^42" ), input); |
| 22 | |
| 23 | // ***** underlying has no format-spec |
| 24 | |
| 25 | // *** align-fill & width *** |
| 26 | check(SV("[true, true, false] " ), SV("{:24}" ), input); |
| 27 | check(SV("[true, true, false]*****" ), SV("{:*<24}" ), input); |
| 28 | check(SV("__[true, true, false]___" ), SV("{:_^24}" ), input); |
| 29 | check(SV("#####[true, true, false]" ), SV("{:#>24}" ), input); |
| 30 | |
| 31 | check(SV("[true, true, false] " ), SV("{:{}}" ), input, 24); |
| 32 | check(SV("[true, true, false]*****" ), SV("{:*<{}}" ), input, 24); |
| 33 | check(SV("__[true, true, false]___" ), SV("{:_^{}}" ), input, 24); |
| 34 | check(SV("#####[true, true, false]" ), SV("{:#>{}}" ), input, 24); |
| 35 | |
| 36 | check_exception("The format string contains an invalid escape sequence" , SV("{:}<}" ), input); |
| 37 | check_exception("The fill option contains an invalid value" , SV("{:{<}" ), input); |
| 38 | |
| 39 | // *** sign *** |
| 40 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:-}" ), input); |
| 41 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:+}" ), input); |
| 42 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{: }" ), input); |
| 43 | |
| 44 | // *** alternate form *** |
| 45 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:#}" ), input); |
| 46 | |
| 47 | // *** zero-padding *** |
| 48 | check_exception("The width option should not have a leading zero" , SV("{:0}" ), input); |
| 49 | |
| 50 | // *** precision *** |
| 51 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:.}" ), input); |
| 52 | |
| 53 | // *** locale-specific form *** |
| 54 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{:L}" ), input); |
| 55 | |
| 56 | // *** n |
| 57 | check(SV("__true, true, false___" ), SV("{:_^22n}" ), input); |
| 58 | |
| 59 | // *** type *** |
| 60 | check_exception("Type m requires a pair or a tuple with two elements" , SV("{:m}" ), input); |
| 61 | check_exception("Type s requires character type as formatting argument" , SV("{:s}" ), input); |
| 62 | check_exception("Type ?s requires character type as formatting argument" , SV("{:?s}" ), input); |
| 63 | |
| 64 | for (std::basic_string_view<CharT> fmt : fmt_invalid_types<CharT>("s" )) |
| 65 | check_exception("The format specifier should consume the input or end with a '}'" , fmt, input); |
| 66 | |
| 67 | // ***** Only underlying has a format-spec |
| 68 | check(SV("[true , true , false ]" ), SV("{::7}" ), input); |
| 69 | check(SV("[true***, true***, false**]" ), SV("{::*<7}" ), input); |
| 70 | check(SV("[_true__, _true__, _false_]" ), SV("{::_^7}" ), input); |
| 71 | check(SV("[:::true, :::true, ::false]" ), SV("{:::>7}" ), input); |
| 72 | |
| 73 | check(SV("[true , true , false ]" ), SV("{::{}}" ), input, 7); |
| 74 | check(SV("[true***, true***, false**]" ), SV("{::*<{}}" ), input, 7); |
| 75 | check(SV("[_true__, _true__, _false_]" ), SV("{::_^{}}" ), input, 7); |
| 76 | check(SV("[:::true, :::true, ::false]" ), SV("{:::>{}}" ), input, 7); |
| 77 | |
| 78 | check_exception("The format string contains an invalid escape sequence" , SV("{::}<}" ), input); |
| 79 | check_exception("The fill option contains an invalid value" , SV("{::{<}" ), input); |
| 80 | |
| 81 | // *** sign *** |
| 82 | check_exception("The format specifier for a bool does not allow the sign option" , SV("{::-}" ), input); |
| 83 | check_exception("The format specifier for a bool does not allow the sign option" , SV("{::+}" ), input); |
| 84 | check_exception("The format specifier for a bool does not allow the sign option" , SV("{:: }" ), input); |
| 85 | |
| 86 | check(SV("[1, 1, 0]" ), SV("{::-d}" ), input); |
| 87 | check(SV("[+1, +1, +0]" ), SV("{::+d}" ), input); |
| 88 | check(SV("[ 1, 1, 0]" ), SV("{:: d}" ), input); |
| 89 | |
| 90 | // *** alternate form *** |
| 91 | check_exception("The format specifier for a bool does not allow the alternate form option" , SV("{::#}" ), input); |
| 92 | |
| 93 | check(SV("[0x1, 0x1, 0x0]" ), SV("{::#x}" ), input); |
| 94 | |
| 95 | // *** zero-padding *** |
| 96 | check_exception("The format specifier for a bool does not allow the zero-padding option" , SV("{::05}" ), input); |
| 97 | |
| 98 | check(SV("[00001, 00001, 00000]" ), SV("{::05o}" ), input); |
| 99 | |
| 100 | // *** precision *** |
| 101 | check_exception("The format specifier should consume the input or end with a '}'" , SV("{::.}" ), input); |
| 102 | |
| 103 | // *** type *** |
| 104 | for (std::basic_string_view<CharT> fmt : fmt_invalid_nested_types<CharT>("bBdosxX" )) |
| 105 | check_exception("The type option contains an invalid value for a bool formatting argument" , fmt, input); |
| 106 | |
| 107 | // ***** Both have a format-spec |
| 108 | check(SV("^^[:::true, :::true, ::false]^^^" ), SV("{:^^32::>7}" ), input); |
| 109 | check(SV("^^[:::true, :::true, ::false]^^^" ), SV("{:^^{}::>7}" ), input, 32); |
| 110 | check(SV("^^[:::true, :::true, ::false]^^^" ), SV("{:^^{}::>{}}" ), input, 32, 7); |
| 111 | |
| 112 | check_exception( |
| 113 | "The argument index value is too large for the number of arguments supplied" , SV("{:^^{}::>5}" ), input); |
| 114 | check_exception( |
| 115 | "The argument index value is too large for the number of arguments supplied" , SV("{:^^{}::>{}}" ), input, 32); |
| 116 | } |
| 117 | |
| 118 | template <class CharT, class TestFunction, class ExceptionTest> |
| 119 | void format_tests(TestFunction check, ExceptionTest check_exception) { |
| 120 | format_test_vector_bool<CharT>(check, check_exception, std::vector{true, true, false}); |
| 121 | |
| 122 | // The const_reference shall be a bool. |
| 123 | // However libc++ uses a __bit_const_reference<vector> when |
| 124 | // _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL is defined. |
| 125 | const std::vector input{true, true, false}; |
| 126 | format_test_vector_bool<CharT>(check, check_exception, input); |
| 127 | } |
| 128 | |
| 129 | #endif // TEST_STD_CONTAINERS_SEQUENCES_VECTOR_BOOL_VECTOR_BOOL_FMT_FORMAT_FUNCTIONS_TESTS_H |
| 130 | |