Viewing file: mathreference.h (4 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// Copyright (C) 2020-2022 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>.
#include <tuple> #include <utility> #include <cstdio>
template <typename T> struct SincosReference { T x, s, c;
std::tuple<const T &, const T &, const T &> as_tuple() const { return std::tie(x, s, c); } };
template <typename T> struct Reference { T x, ref;
std::tuple<const T &, const T &> as_tuple() const { return std::tie(x, ref); } };
template <typename T> struct Array { std::size_t size_; const T *data_;
Array() : size_(0), data_(nullptr) {}
Array(size_t s, const T *p) : size_(s), data_(p) {}
const T* begin() const { return data_; }
const T* end() const { return data_ + size_; }
std::size_t size() const { return size_; } };
namespace function { struct sincos{ static constexpr const char *const str = "sincos"; }; struct atan { static constexpr const char *const str = "atan"; }; struct asin { static constexpr const char *const str = "asin"; }; struct acos { static constexpr const char *const str = "acos"; }; struct log { static constexpr const char *const str = "ln"; }; struct log2 { static constexpr const char *const str = "log2"; }; struct log10 { static constexpr const char *const str = "log10"; }; }
template <class F> struct testdatatype_for_function { template <class T> using type = Reference<T>; };
template <> struct testdatatype_for_function<function::sincos> { template <class T> using type = SincosReference<T>; };
template <class F, class T> using testdatatype_for_function_t = typename testdatatype_for_function<F>::template type<T>;
template<typename T> struct StaticDeleter { const T *ptr;
StaticDeleter(const T *p) : ptr(p) {}
~StaticDeleter() { delete[] ptr; } };
template <class F, class T> inline std::string filename() { static_assert(std::is_floating_point<T>::value, ""); static const auto cache = std::string("reference-") + F::str + (sizeof(T) == 4 && std::__digits_v<T> == 24 && std::__max_exponent_v<T> == 128 ? "-sp" : (sizeof(T) == 8 && std::__digits_v<T> == 53 && std::__max_exponent_v<T> == 1024 ? "-dp" : (sizeof(T) == 16 && std::__digits_v<T> == 64 && std::__max_exponent_v<T> == 16384 ? "-ep" : (sizeof(T) == 16 && std::__digits_v<T> == 113 && std::__max_exponent_v<T> == 16384 ? "-qp" : "-unknown")))) + ".dat"; return cache; }
template <class Fun, class T, class Ref = testdatatype_for_function_t<Fun, T>> Array<Ref> referenceData() { static Array<Ref> data; if (data.data_ == nullptr) { FILE* file = std::fopen(filename<Fun, T>().c_str(), "rb"); if (file) { std::fseek(file, 0, SEEK_END); const size_t size = std::ftell(file) / sizeof(Ref); std::rewind(file); auto mem = new Ref[size]; static StaticDeleter<Ref> _cleanup(data.data_); data.size_ = std::fread(mem, sizeof(Ref), size, file); data.data_ = mem; std::fclose(file); } else { __builtin_fprintf( stderr, "%s:%d: the reference data %s does not exist in the current " "working directory.\n", __FILE__, __LINE__, filename<Fun, T>().c_str()); __builtin_abort(); } } return data; }
|