/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include namespace apache::thrift::conformance::data { namespace { template void addStringValues(NamedValues& values) { values.emplace_back("", "empty"); values.emplace_back("a", "lower"); values.emplace_back("A", "upper"); values.emplace_back(" a ", "spaces"); values.emplace_back(" a", "leading_space"); values.emplace_back("a ", "trailing_space"); values.emplace_back("Hello", "utf8"); if constexpr (type::base_type_v == type::BaseType::Binary) { values.emplace_back("\x72\x01\xff", "bad_utf8"); } } template void addNumberValues(NamedValues& values) { using T = type::standard_type; using numeric_limits = std::numeric_limits; values.emplace_back(0, "zero"); // Extrema if (numeric_limits::lowest() != numeric_limits::min()) { values.emplace_back(numeric_limits::lowest(), "lowest"); } values.emplace_back(numeric_limits::min(), "min"); values.emplace_back(numeric_limits::max(), "max"); if constexpr (!numeric_limits::is_integer) { values.emplace_back(1UL << numeric_limits::digits, "max_int"); values.emplace_back(-values.back().value, "min_int"); values.emplace_back((1UL << numeric_limits::digits) - 1, "max_digits"); values.emplace_back(-values.back().value, "neg_max_digits"); values.emplace_back(0.1, "one_tenth"); values.emplace_back( std::nextafter(numeric_limits::min(), T(1)), "min_plus_ulp"); values.emplace_back( std::nextafter(numeric_limits::max(), T(1)), "max_minus_ulp"); } if constexpr (numeric_limits::has_infinity) { values.emplace_back(numeric_limits::infinity(), "inf"); values.emplace_back(-numeric_limits::infinity(), "neg_inf"); } // Minutiae values.emplace_back(1, "one"); if constexpr (numeric_limits::is_signed) { values.emplace_back(-1, "neg_one"); } if constexpr (numeric_limits::epsilon() != 0) { values.emplace_back(numeric_limits::epsilon(), "epsilon"); values.emplace_back(-numeric_limits::epsilon(), "neg_epsilon"); } if constexpr (numeric_limits::has_denorm == std::denorm_present) { values.emplace_back(numeric_limits::denorm_min(), "denorm_min"); values.emplace_back(-numeric_limits::denorm_min(), "neg_denorm_min"); } if constexpr (std::is_same_v) { values.emplace_back(1.9156918820264798e-56, "fmt_case_1"); values.emplace_back(3788512123356.9854, "fmt_case_2"); } if constexpr (!key) { if constexpr (numeric_limits::has_quiet_NaN) { values.emplace_back(numeric_limits::quiet_NaN(), "NaN"); } if (auto nzero = -static_cast(0); std::signbit(nzero)) { values.emplace_back(nzero, "neg_zero"); } } } template NamedValues generateValues() { static_assert(type::is_a_v, ""); using T = type::standard_type; NamedValues values; if constexpr (type::is_a_v) { values.emplace_back(true, "true"); values.emplace_back(false, "false"); } else if constexpr (type::is_a_v) { addStringValues(values); } else if constexpr (type::is_a_v) { addNumberValues(values); } else { values.emplace_back(T(), "default"); } return values; } } // namespace template auto ValueGenerator::getInterestingValues() -> const Values& { static auto kValues = generateValues(); return kValues; } template auto ValueGenerator::getKeyValues() -> const Values& { static auto kValues = generateValues(); return kValues; } template struct ValueGenerator; template struct ValueGenerator; template struct ValueGenerator; template struct ValueGenerator; template struct ValueGenerator; template struct ValueGenerator; template struct ValueGenerator; template struct ValueGenerator; template struct ValueGenerator; } // namespace apache::thrift::conformance::data