/** * \file libimp/countof.h * \author mutouyun (orz@orzz.org) * \brief Returns the size of the given range. * \date 2022-03-01 */ #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/size */ namespace detail_countof { template struct trait_has_size { private: template static std::true_type check(decltype(std::declval().size())*); template static std::false_type check(...); public: using type = decltype(check(nullptr)); static constexpr auto value = type::value; }; template struct trait_has_Size { private: template static std::true_type check(decltype(std::declval().Size())*); template static std::false_type check(...); public: using type = decltype(check(nullptr)); static constexpr auto value = type::value; }; template ::value , bool = trait_has_Size::value> struct trait; template struct trait { static constexpr auto countof(T const (&)[N]) noexcept { return N; } }; template struct trait { static constexpr auto countof(C const &c) noexcept(noexcept(c.size())) { return c.size(); } }; template struct trait { static constexpr auto countof(C const &c) noexcept(noexcept(c.Size())) { return c.Size(); } }; } // namespace detail_countof template , typename R = decltype(T::countof(std::declval()))> constexpr R countof(C const &c) noexcept(noexcept(T::countof(c))) { return T::countof(c); } LIBIMP_NAMESPACE_END_