|
||||
File indexing completed on 2025-01-18 09:40:42
0001 // Copyright Paul A. Bristow 2017. 0002 // Copyright John Maddock 2017. 0003 0004 // Use, modification and distribution are subject to the 0005 // Boost Software License, Version 1.0. 0006 // (See accompanying file LICENSE_1_0.txt 0007 // or copy at http://www.boost.org/LICENSE_1_0.txt) 0008 0009 // test_value.hpp 0010 0011 #ifndef TEST_VALUE_HPP 0012 #define TEST_VALUE_HPP 0013 0014 // BOOST_MATH_TEST_VALUE is used to create a test value of suitable type from a decimal digit string. 0015 // Two parameters, both a floating-point literal double like 1.23 (not long double so no suffix L) 0016 // and a decimal digit string const char* like "1.23" must be provided. 0017 // The decimal value represented must be the same of course, with at least enough precision for long double. 0018 // Note there are two gotchas to this approach: 0019 // * You need all values to be real floating-point values 0020 // * and *MUST* include a decimal point (to avoid confusion with an integer literal). 0021 // * It's slow to compile compared to a simple literal. 0022 0023 // Speed is not an issue for a few test values, 0024 // but it's not generally usable in large tables 0025 // where you really need everything to be statically initialized. 0026 0027 // Macro BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE provides a global diagnostic value for create_type. 0028 0029 #include <boost/cstdfloat.hpp> // For float_64_t, float128_t. Must be first include! 0030 #ifndef BOOST_MATH_STANDALONE 0031 #include <boost/lexical_cast.hpp> 0032 #endif 0033 #include <limits> 0034 #include <type_traits> 0035 0036 #ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE 0037 // global int create_type(0); must be defined before including this file. 0038 #endif 0039 0040 #ifdef BOOST_HAS_FLOAT128 0041 typedef __float128 largest_float; 0042 #define BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) x##Q 0043 #define BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS 113 0044 #else 0045 typedef long double largest_float; 0046 #define BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) x##L 0047 #define BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS std::numeric_limits<long double>::digits 0048 #endif 0049 0050 template <class T, class T2> 0051 inline T create_test_value(largest_float val, const char*, const std::true_type&, const T2&) 0052 { // Construct from long double or quad parameter val (ignoring string/const char* str). 0053 // (This is case for MPL parameters = true_ and T2 == false_, 0054 // and MPL parameters = true_ and T2 == true_ cpp_bin_float) 0055 // All built-in/fundamental floating-point types, 0056 // and other User-Defined Types that can be constructed without loss of precision 0057 // from long double suffix L (or quad suffix Q), 0058 // 0059 // Choose this method, even if can be constructed from a string, 0060 // because it will be faster, and more likely to be the closest representation. 0061 // (This is case for MPL parameters = true_type and T2 == true_type). 0062 #ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE 0063 create_type = 1; 0064 #endif 0065 return static_cast<T>(val); 0066 } 0067 0068 template <class T> 0069 inline T create_test_value(largest_float, const char* str, const std::false_type&, const std::true_type&) 0070 { // Construct from decimal digit string const char* @c str (ignoring long double parameter). 0071 // For example, extended precision or other User-Defined types which ARE constructible from a string 0072 // (but not from double, or long double without loss of precision). 0073 // (This is case for MPL parameters = false_type and T2 == true_type). 0074 #ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE 0075 create_type = 2; 0076 #endif 0077 return T(str); 0078 } 0079 0080 template <class T> 0081 inline T create_test_value(largest_float, const char* str, const std::false_type&, const std::false_type&) 0082 { // Create test value using from lexical cast of decimal digit string const char* str. 0083 // For example, extended precision or other User-Defined types which are NOT constructible from a string 0084 // (NOR constructible from a long double). 0085 // (This is case T1 = false_type and T2 == false_type). 0086 #ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE 0087 create_type = 3; 0088 #endif 0089 #if defined(BOOST_MATH_STANDALONE) 0090 static_assert(sizeof(T) == 0, "Can not create a test value using lexical cast of string in standalone mode"); 0091 return T(); 0092 #else 0093 return boost::lexical_cast<T>(str); 0094 #endif 0095 } 0096 0097 // T real type, x a decimal digits representation of a floating-point, for example: 12.34. 0098 // It must include a decimal point (or it would be interpreted as an integer). 0099 0100 // x is converted to a long double by appending the letter L (to suit long double fundamental type), 12.34L. 0101 // x is also passed as a const char* or string representation "12.34" 0102 // (to suit most other types that cannot be constructed from long double without possible loss). 0103 0104 // BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) makes a long double or quad version, with 0105 // suffix a letter L (or Q) to suit long double (or quad) fundamental type, 12.34L or 12.34Q. 0106 // #x makes a decimal digit string version to suit multiprecision and fixed_point constructors, "12.34". 0107 // (Constructing from double or long double (or quad) could lose precision for multiprecision or fixed-point). 0108 0109 // The matching create_test_value function above is chosen depending on the T1 and T2 mpl bool truths. 0110 // The string version from #x is used if the precision of T is greater than long double. 0111 0112 // Example: long double test_value = BOOST_MATH_TEST_VALUE(double, 1.23456789); 0113 0114 #define BOOST_MATH_TEST_VALUE(T, x) create_test_value<T>(\ 0115 BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x),\ 0116 #x,\ 0117 std::integral_constant<bool, \ 0118 std::numeric_limits<T>::is_specialized &&\ 0119 (std::numeric_limits<T>::radix == 2)\ 0120 && (std::numeric_limits<T>::digits <= BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS)\ 0121 && std::is_convertible<largest_float, T>::value>(),\ 0122 std::integral_constant<bool, \ 0123 std::is_constructible<T, const char*>::value>()\ 0124 ) 0125 0126 #if LDBL_MAX_10_EXP > DBL_MAX_10_EXP 0127 #define BOOST_MATH_TEST_HUGE_FLOAT_SUFFIX(x) BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) 0128 #else 0129 #define BOOST_MATH_TEST_HUGE_FLOAT_SUFFIX(x) 0.0 0130 #endif 0131 0132 #define BOOST_MATH_HUGE_TEST_VALUE(T, x) create_test_value<T>(\ 0133 BOOST_MATH_TEST_HUGE_FLOAT_SUFFIX(x),\ 0134 #x,\ 0135 std::integral_constant<bool, \ 0136 std::numeric_limits<T>::is_specialized &&\ 0137 (std::numeric_limits<T>::radix == 2)\ 0138 && (std::numeric_limits<T>::digits <= BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS)\ 0139 && std::is_convertible<largest_float, T>::value>(),\ 0140 std::integral_constant<bool, \ 0141 std::is_constructible<T, const char*>::value>()\ 0142 ) 0143 #endif // TEST_VALUE_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |