//------------------------------------------------------------------------------ // File: TypeTraits.hh // Author: Abhishek Lekshmanan - CERN //------------------------------------------------------------------------------ /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2022 CERN/Switzerland * * * * This program 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 of the License, or * * (at your option) any later version. * * * * This program 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 program. If not, see .* ************************************************************************/ #pragma once /** * @file TypeTraits.hh * * @brief Some useful compile time type traits utilities * * A common place for some simple template type inspection utilities, so that * classes/functions defining them needn't define them at site, everything is * defined in a detail namespace as this functionality isn't meant to be exposed * to outside world but for internal static_asserts/SFINAE use cases */ #include #include // declval, and charconv // version can be used for feature testing macros, while we're not C++20 yet // helpful in case of identifying compiler support for partially supported // C++17 features, for eg. charconv's float conversions which are only // implemented by newer GCC/VS compilers #if __has_include() #include #endif namespace eos::common::detail { // A simple test for containers that expose a C::key_type // Ideally std::remove_if requires a dereferenced iterator to be MoveAssignable // ie *it = std::move(value) to be legal // However for all assoc. containers this would be illegal as keys have // pointer stability, so this will fail (with long compiler messages) // A poor man's choice of tests for detecting associative containers is just // testing for key_type which is kind of ok for std:: containers template struct is_assoc_container_t : std::false_type {}; template struct is_assoc_container_t>: std::true_type {}; template inline constexpr bool is_assoc_container_v = is_assoc_container_t::value; // A simple test for containers that expose a data() type which is usually defined // for contiguous sequences like string/_view/arrays/vectors template struct has_data_t : std::false_type {}; template struct has_data_t().data())>> : std::true_type {}; // While technically this will be only defined by compilers implementing, given // that preprocessors will replace unknowns with 0s, we'll have valid arithmetic // expressions to write forward compatible code #if __cpp_lib_to_chars >= 201611 // We are dealing with a compiler fully implementing charconv including floats template inline constexpr bool is_charconv_numeric_v = std::is_arithmetic::value; #else // Partial implementation only for integral types for eg. clang/gcc < 11 template inline constexpr bool is_charconv_numeric_v = std::is_integral::value; #endif } // eos::common::detail