| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 
 | //===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14
// <charconv>
// constexpr from_chars_result from_chars(const char* first, const char* last,
//                                        Integral& value, int base = 10)
#include <charconv>
#include "test_macros.h"
#include "charconv_test_helpers.h"
template <typename T>
struct test_basics
{
    TEST_CONSTEXPR_CXX23 void operator()()
    {
        std::from_chars_result r;
        T x;
        {
            char s[] = "001x";
            // the expected form of the subject sequence is a sequence of
            // letters and digits representing an integer with the radix
            // specified by base (C11 7.22.1.4/3)
            r = std::from_chars(s, s + sizeof(s), x);
            assert(r.ec == std::errc{});
            assert(r.ptr == s + 3);
            assert(x == 1);
        }
        {
            // The string has more characters than valid in an 128-bit value.
            char s[] = "0X7BAtSGHDkEIXZgQRfYChLpOzRnM ";
            // The letters from a (or A) through z (or Z) are ascribed the
            // values 10 through 35; (C11 7.22.1.4/3)
            r = std::from_chars(s, s + sizeof(s), x, 36);
            assert(r.ec == std::errc::result_out_of_range);
            // The member ptr of the return value points to the first character
            // not matching the pattern
            assert(r.ptr == s + sizeof(s) - 2);
            assert(x == 1);
            // no "0x" or "0X" prefix shall appear if the value of base is 16
            r = std::from_chars(s, s + sizeof(s), x, 16);
            assert(r.ec == std::errc{});
            assert(r.ptr == s + 1);
            assert(x == 0);
            // only letters and digits whose ascribed values are less than that
            // of base are permitted. (C11 7.22.1.4/3)
            r = std::from_chars(s + 2, s + sizeof(s), x, 12);
            // If the parsed value is not in the range representable by the type
            // of value,
            if (!fits_in<T>(1150))
            {
                // value is unmodified and
                assert(x == 0);
                // the member ec of the return value is equal to
                // errc::result_out_of_range
                assert(r.ec == std::errc::result_out_of_range);
            }
            else
            {
                // Otherwise, value is set to the parsed value,
                assert(x == 1150);
                // and the member ec is value-initialized.
                assert(r.ec == std::errc{});
            }
            assert(r.ptr == s + 5);
        }
    }
};
template <typename T>
struct test_signed
{
    TEST_CONSTEXPR_CXX23 void operator()()
    {
        std::from_chars_result r;
        T x = 42;
        {
            // If the pattern allows for an optional sign,
            // but the string has no digit characters following the sign,
            char s[] = "- 9+12";
            r = std::from_chars(s, s + sizeof(s), x);
            // value is unmodified,
            assert(x == 42);
            // no characters match the pattern.
            assert(r.ptr == s);
            assert(r.ec == std::errc::invalid_argument);
        }
        {
            char s[] = "9+12";
            r = std::from_chars(s, s + sizeof(s), x);
            assert(r.ec == std::errc{});
            // The member ptr of the return value points to the first character
            // not matching the pattern,
            assert(r.ptr == s + 1);
            assert(x == 9);
        }
        {
            char s[] = "12";
            r = std::from_chars(s, s + 2, x);
            assert(r.ec == std::errc{});
            // or has the value last if all characters match.
            assert(r.ptr == s + 2);
            assert(x == 12);
        }
        {
            // '-' is the only sign that may appear
            char s[] = "+30";
            // If no characters match the pattern,
            r = std::from_chars(s, s + sizeof(s), x);
            // value is unmodified,
            assert(x == 12);
            // the member ptr of the return value is first and
            assert(r.ptr == s);
            // the member ec is equal to errc::invalid_argument.
            assert(r.ec == std::errc::invalid_argument);
        }
    }
};
TEST_CONSTEXPR_CXX23 bool test()
{
    run<test_basics>(integrals);
    run<test_signed>(all_signed);
    return true;
}
int main(int, char**) {
    test();
#if TEST_STD_VER > 20
    static_assert(test());
#endif
    return 0;
}
 |