//===----------------------------------------------------------------------===//
//
// 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, c++17, c++20
// <format>
// template<class T>
// constexpr bool enable_nonlocking_formatter_optimization = false;
// Remarks: Pursuant to [namespace.std], users may specialize
// enable_nonlocking_formatter_optimization for cv-unqualified program-defined
// types. Such specializations shall be usable in constant expressions
// ([expr.const]) and have type const bool.
// [format.formatter.spec]
// In addition, for each type T for which a formatter specialization is provided
// above, each of the headers provides the following specialization:
//
// template<>
// inline constexpr bool enable_nonlocking_formatter_optimization<T> = true;
#include <array>
#include <bitset>
#include <bitset>
#include <chrono>
#include <complex>
#include <concepts>
#include <deque>
#include <filesystem>
#include <format>
#include <forward_list>
#include <list>
#include <map>
#include <memory>
#include <optional>
#include <queue>
#include <set>
#include <span>
#include <stack>
#include <system_error>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <variant>
#include <vector>
#include "test_macros.h"
#include "min_allocator.h"
#ifndef TEST_HAS_NO_LOCALIZATION
# include <regex>
#endif
#ifndef TEST_HAS_NO_THREADS
# include <thread>
#endif
// Tests for P0645 Text Formatting
template <class CharT>
void test_P0645() {
static_assert(std::enable_nonlocking_formatter_optimization<CharT>);
static_assert(std::enable_nonlocking_formatter_optimization<CharT*>);
static_assert(std::enable_nonlocking_formatter_optimization<const CharT*>);
static_assert(std::enable_nonlocking_formatter_optimization<CharT[42]>);
static_assert(std::enable_nonlocking_formatter_optimization<std::basic_string<CharT>>);
static_assert(std::enable_nonlocking_formatter_optimization<std::basic_string_view<CharT>>);
static_assert(std::enable_nonlocking_formatter_optimization<bool>);
static_assert(std::enable_nonlocking_formatter_optimization<signed char>);
static_assert(std::enable_nonlocking_formatter_optimization<signed short>);
static_assert(std::enable_nonlocking_formatter_optimization<signed int>);
static_assert(std::enable_nonlocking_formatter_optimization<signed long>);
static_assert(std::enable_nonlocking_formatter_optimization<signed long long>);
#ifndef TEST_HAS_NO_INT128
static_assert(std::enable_nonlocking_formatter_optimization<__int128_t>);
#endif
static_assert(std::enable_nonlocking_formatter_optimization<unsigned char>);
static_assert(std::enable_nonlocking_formatter_optimization<unsigned short>);
static_assert(std::enable_nonlocking_formatter_optimization<unsigned int>);
static_assert(std::enable_nonlocking_formatter_optimization<unsigned long>);
static_assert(std::enable_nonlocking_formatter_optimization<unsigned long long>);
#ifndef TEST_HAS_NO_INT128
static_assert(std::enable_nonlocking_formatter_optimization<__uint128_t>);
#endif
static_assert(std::enable_nonlocking_formatter_optimization<float>);
static_assert(std::enable_nonlocking_formatter_optimization<double>);
static_assert(std::enable_nonlocking_formatter_optimization<long double>);
static_assert(std::enable_nonlocking_formatter_optimization<std::nullptr_t>);
static_assert(std::enable_nonlocking_formatter_optimization<void*>);
static_assert(std::enable_nonlocking_formatter_optimization<const void*>);
}
// Tests for P1361 Integration of chrono with text formatting
//
// Some tests are commented out since these types haven't been implemented in
// chrono yet. After P1361 has been implemented these formatters should be all
// enabled.
void test_P1361() {
// The chrono formatters require localization support.
// [time.format]/7
// If the chrono-specs is omitted, the chrono object is formatted as if by
// streaming it to std::ostringstream os with the formatting
// locale imbued and copying os.str() through the output iterator of the
// context with additional padding and adjustments as specified by the format
// specifiers.
// In libc++ std:::ostringstream requires localization support.
#ifndef TEST_HAS_NO_LOCALIZATION
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::microseconds>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::sys_time<std::chrono::microseconds>>);
//static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::utc_time<std::chrono::microseconds>>);
//static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::tai_time<std::chrono::microseconds>>);
//static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::gps_time<std::chrono::microseconds>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::file_time<std::chrono::microseconds>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::local_time<std::chrono::microseconds>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::day>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::month>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::year>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::weekday>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::weekday_indexed>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::weekday_last>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::month_day>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::month_day_last>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::month_weekday>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::month_weekday_last>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::year_month>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::year_month_day>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::year_month_day_last>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::year_month_weekday>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::year_month_weekday_last>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::hh_mm_ss<std::chrono::microseconds>>);
//static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::sys_info>);
//static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::local_info>);
//static_assert(!std::enable_nonlocking_formatter_optimization<std::chrono::zoned_time>);
#endif // TEST_HAS_NO_LOCALIZATION
}
// Tests for P1636 Formatters for library types
//
// The paper hasn't been voted in so currently all formatters are disabled.
// Note the paper has been abandoned, the types are kept since other papers may
// introduce these formatters.
void test_P1636() {
#ifndef TEST_HAS_NO_THREADS
static_assert(!std::enable_nonlocking_formatter_optimization<std::thread::id>);
#endif
}
template <class Vector>
void test_P2286_vector_bool() {
static_assert(!std::enable_nonlocking_formatter_optimization<Vector>);
static_assert(!std::enable_nonlocking_formatter_optimization<typename Vector::reference>);
// The const_reference shall be a bool.
// However libc++ uses a __bit_const_reference<vector> when
// _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL is defined.
static_assert(!std::enable_nonlocking_formatter_optimization<const Vector&>);
static_assert(std::enable_nonlocking_formatter_optimization<typename Vector::const_reference> ==
std::same_as<typename Vector::const_reference, bool>);
}
// Tests for P2286 Formatting ranges
void test_P2286() {
static_assert(!std::enable_nonlocking_formatter_optimization<std::array<int, 42>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::vector<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::deque<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::forward_list<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::list<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::set<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::map<int, int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::multiset<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::multimap<int, int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::unordered_set<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::unordered_map<int, int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::unordered_multiset<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::unordered_multimap<int, int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::stack<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::queue<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::priority_queue<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::span<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::valarray<int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::pair<int, int>>);
static_assert(!std::enable_nonlocking_formatter_optimization<std::tuple<int>>);
test_P2286_vector_bool<std::vector<bool>>();
test_P2286_vector_bool<std::vector<bool, std::allocator<bool>>>();
test_P2286_vector_bool<std::vector<bool, min_allocator<bool>>>();
}
// The trait does not care about whether the type is formattable, obviously the
// trait for non formattable types are not used.
struct not_formattable_nonlocking_disabled {};
static_assert(!std::enable_nonlocking_formatter_optimization<not_formattable_nonlocking_disabled>);
struct not_formattable_nonlocking_enabled {};
template <>
inline constexpr bool std::enable_nonlocking_formatter_optimization<not_formattable_nonlocking_enabled> = true;
static_assert(std::enable_nonlocking_formatter_optimization<not_formattable_nonlocking_enabled>);
void test() {
test_P0645<char>();
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
test_P0645<wchar_t>();
#endif
test_P1361();
test_P1636();
test_P2286();
}