Add trait to check whether type is iteratable

This commit is contained in:
Martchus 2017-05-08 19:51:24 +02:00
parent db46948f2f
commit f827c2be00
1 changed files with 23 additions and 0 deletions

View File

@ -1,6 +1,7 @@
#ifndef CPP_UTILITIES_TRAITS_H
#define CPP_UTILITIES_TRAITS_H
#include <iterator>
#include <type_traits>
/// \brief Contains traits for conveniently exploiting SFINAE.
@ -39,6 +40,28 @@ template <typename T, template <typename...> class Template> struct IsSpecializa
};
template <template <typename...> class Template, typename... Args> struct IsSpecializationOf<Template<Args...>, Template> : Bool<true> {
};
/// \cond
namespace Detail {
// allow ADL with custom begin/end
using std::begin;
using std::end;
template <typename T>
auto isIteratableImpl(int) -> decltype(
// begin/end and operator !=
begin(std::declval<T &>()) != end(std::declval<T &>()),
// operator ,
void(),
// operator ++
++std::declval<decltype(begin(std::declval<T &>())) &>(),
// operator*
void(*begin(std::declval<T &>())), Bool<true>{});
template <typename T> Bool<false> isIteratableImpl(...);
}
/// \endcond
template <typename T> using IsIteratable = decltype(Detail::isIteratableImpl<T>(0));
}
#endif // CPP_UTILITIES_TRAITS_H