/** * \file libimp/dataof.h * \author mutouyun (orz@orzz.org) * \brief Returns the data pointer of the given range * \date 2023-05-27 */ #pragma once #include // std::declval, std::true_type, std::false_type #include // std::size_t #include "libimp/def.h" #include "libimp/generic.h" LIBIMP_NAMESPACE_BEG_ /** * \see https://en.cppreference.com/w/cpp/iterator/data */ namespace detail_dataof { template struct trait_has_data { private: template static std::true_type check(decltype(std::declval().data())*); template static std::false_type check(...); public: using type = decltype(check(nullptr)); constexpr static auto value = type::value; }; template struct trait_has_Data { private: template static std::true_type check(decltype(std::declval().Data())*); template static std::false_type check(...); public: using type = decltype(check(nullptr)); constexpr static auto value = type::value; }; template ::value , bool = trait_has_Data::value> struct trait; template struct trait { constexpr static T const *dataof(T const (&arr)[N]) noexcept { return arr; } constexpr static T *dataof(T (&arr)[N]) noexcept { return arr; } }; template struct trait { template constexpr static auto dataof(T &&c) noexcept(noexcept(c.data())) { return std::forward(c).data(); } }; template struct trait { template constexpr static auto dataof(T &&c) noexcept(noexcept(c.Data())) { return std::forward(c).Data(); } }; template struct trait { template constexpr static T const *dataof(std::initializer_list il) noexcept { return il.begin(); } }; } // namespace detail_dataof template >>> constexpr auto dataof(T &&c) noexcept(noexcept(R::dataof(std::forward(c)))) { return R::dataof(std::forward(c)); } LIBIMP_NAMESPACE_END_