.. _program_listing_file_src_sparsebase_utils_utils.h: Program Listing for File utils.h ================================ |exhale_lsh| :ref:`Return to documentation for file ` (``src/sparsebase/utils/utils.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /******************************************************* * Copyright (c) 2022 SparCity, Amro Alabsi Aljundi, Taha Atahan Akyildiz, Arda *Sener All rights reserved. * * This file is distributed under MIT license. * The complete license agreement can be obtained at: * https://sparcityeu.github.io/sparsebase/pages/license.html ********************************************************/ #ifndef SPARSEBASE_SPARSEBASE_UTILS_H_ #define SPARSEBASE_SPARSEBASE_UTILS_H_ #include #include #include #include #include #include #include #include "exception.h" namespace sparsebase::utils { typedef float CostType; // Thanks to artificial mind blog: // https://artificial-mind.net/blog/2020/10/03/always-false template constexpr bool always_false = false; struct TypeIndexVectorHash { std::size_t operator()(const std::vector &vf) const; }; using std::numeric_limits; // Cross float-integral type conversion is not currently available template bool CanTypeFitValue(const U value) { bool decision; if constexpr (std::is_integral_v != std::is_integral_v) decision = false; if constexpr (std::is_integral_v && std::is_integral_v) { const intmax_t botT = []() { intmax_t ret; if constexpr (std::is_floating_point_v) ret = intmax_t(-(numeric_limits::max())); else ret = intmax_t(numeric_limits::min()); return ret; }(); const intmax_t botU = []() { intmax_t ret; if constexpr (std::is_floating_point_v) ret = intmax_t(-(numeric_limits::max())); else ret = intmax_t(numeric_limits::min()); return ret; }(); const uintmax_t topT = uintmax_t(numeric_limits::max()); const uintmax_t topU = uintmax_t(numeric_limits::max()); decision = !((botT > botU && value < (U)(botT)) || (topT < topU && value > (U)(topT))); } else if constexpr (!std::is_integral_v && !std::is_integral_v) { const double botT = []() { T ret; if constexpr (std::is_floating_point_v) ret = T(-(numeric_limits::max())); else ret = T(numeric_limits::min()); return ret; }(); const double botU = []() { U ret; if constexpr (std::is_floating_point_v) ret = U(-(numeric_limits::max())); else ret = U(numeric_limits::min()); return ret; }(); const double topT = numeric_limits::max(); const double topU = numeric_limits::max(); decision = !((botT > botU && value < (U)(botT)) || (topT < topU && value > (U)(topT))); } return decision; //} else if constexpr (std::is_integral_v && !std::is_integral_v ){ // const double topT = double(numeric_limits::max()); // const uintmax_t topU = uintmax_t(numeric_limits::max()); // const double botT = []() { // if constexpr (std::is_floating_point_v) // return double(-(numeric_limits::max())); // else // return double(numeric_limits::min()); // }(); // const intmax_t botU = []() { // if constexpr (std::is_floating_point_v) // return intmax_t(-(numeric_limits::max())); // else // return intmax_t(numeric_limits::min()); // }(); // return !(double(topU) > topT && double(value) > topT) || !(double(botU) < // botT && double(value) > topT); //} else { // const uintmax_t topT = uintmax_t(numeric_limits::max()); // const double topU = double(numeric_limits::max()); // const intmax_t botT = []() { // if constexpr (std::is_floating_point_v) // return intmax_t(-(numeric_limits::max())); // else // return intmax_t(numeric_limits::min()); // }(); // const double botU = []() { // if constexpr (std::is_floating_point_v) // return double(-(numeric_limits::max())); // else // return double(numeric_limits::min()); // }(); // return !(topU > double(topT) && value > double(topT)) || !(botU < // double(botT) && value > double(topT)); //} } template inline bool isTypeConversionSafe(FromType from_val, ToType to_val) { return from_val == to_val && CanTypeFitValue(from_val); } template ToType *ConvertArrayType(FromType *from_ptr, SizeType size) { if constexpr (!(std::is_same_v && std::is_same_v)) { if (from_ptr == nullptr) return nullptr; auto to_ptr = new ToType[size]; for (SizeType i = 0; i < size; i++) { to_ptr[i] = from_ptr[i]; if (!isTypeConversionSafe(from_ptr[i], to_ptr[i])) { throw utils::TypeException( "Could not convert array from type " + std::string(std::type_index(typeid(FromType)).name()) + " to type " + std::string(std::type_index(typeid(ToType)).name()) + ". Overflow detected"); } } return to_ptr; } return nullptr; } template class OnceSettable { public: OnceSettable() : is_set_(false) {} operator T() const { return data_; } OnceSettable(const OnceSettable &) = delete; OnceSettable(OnceSettable &&) = delete; OnceSettable &operator=(T &&data) { if (!is_set_) { data_ = std::move(data); is_set_ = true; return *this; } throw utils::AttemptToReset(); } const T &get() const { return data_; } private: T data_; bool is_set_; }; std::string demangle(const std::string &name); std::string demangle(std::type_index type); class Identifiable { public: virtual std::type_index get_id() const = 0; virtual std::string get_name() const = 0; }; template class IdentifiableImplementation : public Base { public: virtual std::type_index get_id() const { return typeid(IdentifiableType); } virtual std::string get_name() const { return utils::demangle(get_id()); }; static std::type_index get_id_static() { return typeid(IdentifiableType); } static std::string get_name_static() { return utils::demangle(get_id_static()); }; }; template struct Implementation { public: Implementation() = default; template explicit Implementation(ConcreteType &&object) : storage{std::forward(object)}, getter{[](std::any &storage) -> Interface & { return std::any_cast(storage); }} {} Implementation(const Implementation &object) : storage{object.storage}, getter{object.getter} {} Implementation(Implementation &&object) noexcept : storage{std::move(object.storage)}, getter{std::move(object.getter)} {} Implementation &operator=(Implementation other) { storage = other.storage; getter = other.getter; return *this; } Interface *operator->() { return &getter(storage); } private: std::any storage; Interface &(*getter)(std::any &); }; } // namespace sparsebase::utils #ifdef _HEADER_ONLY #include "sparsebase/utils/utils.cc" #endif #endif