//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef SUPPORT_CHARCONV_TEST_HELPERS_H
#define SUPPORT_CHARCONV_TEST_HELPERS_H

#include <charconv>
#include <cassert>
#include <limits>
#include <numeric>
#include <string.h>
#include <stdlib.h>

#include "test_macros.h"

#if TEST_STD_VER < 11
#error This file requires C++11
#endif

using std::false_type;
using std::true_type;

template <typename To, typename From>
constexpr auto
is_non_narrowing(From a) -> decltype(To{a}, true_type())
{
    return {};
}

template <typename To>
constexpr auto
is_non_narrowing(...) -> false_type
{
    return {};
}

template <typename X, typename T>
constexpr bool
_fits_in(T, true_type /* non-narrowing*/, ...)
{
    return true;
}

template <typename X, typename T, typename xl = std::numeric_limits<X>>
constexpr bool
_fits_in(T v, false_type, true_type /* T signed*/, true_type /* X signed */)
{
    return xl::lowest() <= v && v <= (xl::max)();
}

template <typename X, typename T, typename xl = std::numeric_limits<X>>
constexpr bool
_fits_in(T v, false_type, true_type /* T signed */, false_type /* X unsigned*/)
{
    return 0 <= v && typename std::make_unsigned<T>::type(v) <= (xl::max)();
}

template <typename X, typename T, typename xl = std::numeric_limits<X>>
constexpr bool
_fits_in(T v, false_type, false_type /* T unsigned */, ...)
{
    return v <= typename std::make_unsigned<X>::type((xl::max)());
}

template <typename X, typename T>
constexpr bool
fits_in(T v)
{
    return _fits_in<X>(v, is_non_narrowing<X>(v), std::is_signed<T>(),
                       std::is_signed<X>());
}

template <typename X>
struct to_chars_test_base
{
    template <typename T, size_t N, typename... Ts>
    void test(T v, char const (&expect)[N], Ts... args)
    {
        using std::to_chars;
        std::to_chars_result r;

        constexpr size_t len = N - 1;
        static_assert(len > 0, "expected output won't be empty");

        if (!fits_in<X>(v))
            return;

        r = to_chars(buf, buf + len - 1, X(v), args...);
        assert(r.ptr == buf + len - 1);
        assert(r.ec == std::errc::value_too_large);

        r = to_chars(buf, buf + sizeof(buf), X(v), args...);
        assert(r.ptr == buf + len);
        assert(r.ec == std::errc{});
        assert(memcmp(buf, expect, len) == 0);
    }

    template <typename... Ts>
    void test_value(X v, Ts... args)
    {
        using std::to_chars;
        std::to_chars_result r;

        // Poison the buffer for testing whether a successful std::to_chars
        // doesn't modify data beyond r.ptr.
        std::iota(buf, buf + sizeof(buf), 1);
        r = to_chars(buf, buf + sizeof(buf), v, args...);
        assert(r.ec == std::errc{});
        for (size_t i = r.ptr - buf; i < sizeof(buf); ++i)
            assert(buf[i] == static_cast<char>(i + 1));
        *r.ptr = '\0';

        auto a = fromchars(buf, r.ptr, args...);
        assert(v == a);

        auto ep = r.ptr - 1;
        r = to_chars(buf, ep, v, args...);
        assert(r.ptr == ep);
        assert(r.ec == std::errc::value_too_large);
    }

private:
    static long long fromchars(char const* p, char const* ep, int base, true_type)
    {
        char* last;
        auto r = strtoll(p, &last, base);
        assert(last == ep);

        return r;
    }

    static unsigned long long fromchars(char const* p, char const* ep, int base, false_type)
    {
        char* last;
        auto r = strtoull(p, &last, base);
        assert(last == ep);

        return r;
    }

    static auto fromchars(char const* p, char const* ep, int base = 10)
    -> decltype(fromchars(p, ep, base, std::is_signed<X>()))
    {
        return fromchars(p, ep, base, std::is_signed<X>());
    }

    char buf[100];
};

template <typename X>
struct roundtrip_test_base
{
    template <typename T, typename... Ts>
    void test(T v, Ts... args)
    {
        using std::from_chars;
        using std::to_chars;
        std::from_chars_result r2;
        std::to_chars_result r;
        X x = 0xc;

        if (fits_in<X>(v))
        {
            r = to_chars(buf, buf + sizeof(buf), v, args...);
            assert(r.ec == std::errc{});

            r2 = from_chars(buf, r.ptr, x, args...);
            assert(r2.ptr == r.ptr);
            assert(x == X(v));
        }
        else
        {
            r = to_chars(buf, buf + sizeof(buf), v, args...);
            assert(r.ec == std::errc{});

            r2 = from_chars(buf, r.ptr, x, args...);

#ifdef TEST_COMPILER_C1XX
    #pragma warning(push)
    #pragma warning(disable: 4127) // conditional expression is constant
#endif // TEST_COMPILER_C1XX
            if (std::is_signed<T>::value && v < 0 && std::is_unsigned<X>::value)
            {
                assert(x == 0xc);
                assert(r2.ptr == buf);
                assert(r2.ec == std::errc::invalid_argument);
            }
            else
            {
                assert(x == 0xc);
                assert(r2.ptr == r.ptr);
                assert(r2.ec == std::errc::result_out_of_range);
            }
#ifdef TEST_COMPILER_C1XX
    #pragma warning(pop)
#endif // TEST_COMPILER_C1XX
        }
    }

private:
    char buf[100];
};

template <typename... T>
struct type_list
{
};

template <typename L1, typename L2>
struct type_concat;

template <typename... Xs, typename... Ys>
struct type_concat<type_list<Xs...>, type_list<Ys...>>
{
    using type = type_list<Xs..., Ys...>;
};

template <typename L1, typename L2>
using concat_t = typename type_concat<L1, L2>::type;

template <typename L1, typename L2>
constexpr auto concat(L1, L2) -> concat_t<L1, L2>
{
    return {};
}

auto all_signed = type_list<char, signed char, short, int, long, long long>();
auto all_unsigned = type_list<unsigned char, unsigned short, unsigned int,
                              unsigned long, unsigned long long>();
auto integrals = concat(all_signed, all_unsigned);

template <template <typename> class Fn, typename... Ts>
void
run(type_list<Ts...>)
{
    int ls[sizeof...(Ts)] = {(Fn<Ts>{}(), 0)...};
    (void)ls;
}

#endif // SUPPORT_CHARCONV_TEST_HELPERS_H
