/* ***************************************************************************** * kblib is a general utility library for C++14 and C++17, intended to provide * performant high-level abstractions and more expressive ways to do simple * things. * * Copyright (c) 2021 killerbee * * 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 . * ****************************************************************************/ /** * @file * @brief Provides macros and basic templates used by the rest of kblib. * * @author killerbee * @date 2019-2021 * @copyright GNU General Public Licence v3.0 */ #ifndef KBLIB_TDECL_H #define KBLIB_TDECL_H #include #if __cplusplus < 201402L # error kblib requires C++14 or higher #endif #define KBLIB_X(X) X #define KBLIB_VERS_MAJ 00 #define KBLIB_VERS_MIN 04 #define KBLIB_VERS_REV 00 #define KBLIB_VERS_I(P, MAJ, MIN, REV) KBLIB_VERS_I2(P, MAJ, MIN, REV) #define KBLIB_VERS_I2(P, MAJ, MIN, REV) P##MAJ##MIN##REV // VMMmmrr #define KBLIB_VERS_S \ KBLIB_VERS_I(KBV, KBLIB_VERS_MAJ, KBLIB_VERS_MIN, KBLIB_VERS_REV) // 1MMmmrr #define KBLIB_VERS \ KBLIB_VERS_I(1, KBLIB_VERS_MAJ, KBLIB_VERS_MIN, KBLIB_VERS_REV) /** * @def KBLIB_USE_CXX17 * @brief This internal macro is used to determine if kblib can use C++17 * features. */ #if (__cplusplus >= 201703L) # define KBLIB_USE_CXX17 1 #else # define KBLIB_USE_CXX17 0 #endif /** * @def KBLIB_USE_CXX20 * @brief This internal macro is used to determine if kblib can use C++20 * features. */ #if (__cplusplus >= 202002L) # define KBLIB_USE_CXX20 1 #else # define KBLIB_USE_CXX20 0 #endif /** * @def KBLIB_USE_STRING_VIEW * @brief This internal macro is used to determine if kblib can use C++17's * std::string_view. */ #ifndef KBLIB_USE_STRING_VIEW # if KBLIB_USE_CXX17 # define KBLIB_USE_STRING_VIEW 1 # else # define KBLIB_USE_STRING_VIEW 0 # endif #endif /** * @def KBLIB_CXX20 * @brief This internal macro is used to selectively use C++20 features. */ #if KBLIB_USE_CXX20 # define KBLIB_CXX20(args) args #else # define KBLIB_CXX20(args) #endif // used to prevent cross-linkage between incompatible library versions #define KBLIB_VERS_NS_I(VS, CXX17, CXX_SV, CXX20) \ KBLIB_VERS_NS_I2(VS, CXX17, CXX_SV, CXX20) #define KBLIB_VERS_NS_I2(VS, CXX17, CXX_SV, CXX20) VS##_##CXX17##CXX_SV##CXX20 #define KBLIB_VERS_NS \ KBLIB_VERS_NS_I(KBLIB_VERS_S, KBLIB_USE_CXX17, KBLIB_USE_STRING_VIEW, \ KBLIB_USE_CXX20) #ifndef _DOXYGEN_ # define KBLIB_NS KBLIB_VERS_NS namespace KBLIB_NS {} namespace kblib = KBLIB_NS; #else # define KBLIB_NS kblib #endif // Note that __has_cpp_attribute(nodiscard) does not work with at least certain // versions of Clang /** * @def KBLIB_NODISCARD * @brief This internal macro is used to provide a fallback for [[nodiscard]] * in C++14. */ /** * @def KBLIB_UNUSED * @brief This internal macro is used to provide a fallback for [[maybe_unused]] * in C++14. */ #if KBLIB_USE_CXX17 # define KBLIB_NODISCARD [[nodiscard]] # define KBLIB_UNUSED [[maybe_unused]] #else # define KBLIB_NODISCARD [[gnu::warn_unused_result]] # define KBLIB_UNUSED [[gnu::unused]] #endif #if KBLIB_USE_CXX17 # define KBLIB_CONSTANT constexpr inline # define KBLIB_CONSTANT_V constexpr inline bool # define KBLIB_CONSTANT_M constexpr inline static # define KBLIB_CONSTANT_MV constexpr inline static bool #else # define KBLIB_CONSTANT constexpr # define KBLIB_CONSTANT_V constexpr bool # define KBLIB_CONSTANT_M constexpr static # define KBLIB_CONSTANT_MV constexpr static bool #endif #if defined(_DOXYGEN_) and not defined(KBLIB_DEF_MACROS) /** * @def KBLIB_DEF_MACROS * @brief If this macro is defined, kblib will define certain macros without the * KBLIB_ prefix. */ # define KBLIB_DEF_MACROS #endif /** * @namespace kblib * @brief The main namespace in which all entities from kblib are defined. */ namespace KBLIB_NS { /** * @namespace kblib::detail * @brief The namespace used for implementation details within kblib. * * @internal */ namespace detail { template struct buildiota_impl; template struct tag { using type = T; }; template struct no_dangle { using type = T&; }; template struct no_dangle { using type = T; }; template using no_dangle_t = typename no_dangle::type; } // namespace detail enum class endian { unknown, little, big, weird }; #ifdef __BYTE_ORDER__ namespace detail { KBLIB_NODISCARD constexpr auto get_system_endian() -> endian { if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) { return endian::big; } else if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) { return endian::little; } else { return endian::weird; } } } // namespace detail constexpr endian system_endian = detail::get_system_endian(); #else constexpr endian system_endian = endian::unknown; #endif namespace detail { KBLIB_NODISCARD constexpr auto get_hash_order() -> endian { if (system_endian == endian::little or system_endian == endian::big) { return system_endian; } else { return endian::little; } } } // namespace detail #ifdef KBLIB_CONSISTENT_HASHES constexpr endian hash_order = little; #else constexpr endian hash_order = detail::get_hash_order(); #endif #if KBLIB_USE_CXX17 using std::byte; #else using byte = unsigned char; #endif } // namespace KBLIB_NS #endif // KBLIB_TDECL_H