[iter/meta] Add hb_is_iterable
This commit is contained in:
parent
576d5e2420
commit
8c6cbbdfa3
|
@ -43,6 +43,11 @@
|
|||
* returns rvalues.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Base classes for iterators.
|
||||
*/
|
||||
|
||||
/* Base class for all iterators. */
|
||||
template <typename Iter, typename Item = typename Iter::__item_type__>
|
||||
struct hb_iter_t
|
||||
|
@ -98,8 +103,6 @@ struct hb_iter_t
|
|||
using Name::is_random_access; \
|
||||
static_assert (true, "")
|
||||
|
||||
|
||||
|
||||
/* Base class for sorted iterators. Does not enforce anything.
|
||||
* Just for class taxonomy and requirements. */
|
||||
template <typename Iter, typename Item = typename Iter::__item_type__>
|
||||
|
@ -147,8 +150,25 @@ struct hb_iter_mixin_t
|
|||
void operator = (const hb_iter_mixin_t &o HB_UNUSED) {}
|
||||
};
|
||||
|
||||
/*
|
||||
* Meta-programming predicates.
|
||||
*/
|
||||
|
||||
/* Functions operating on iterators or iteratables. */
|
||||
template<class T, typename B>
|
||||
struct _hb_is_iterable
|
||||
{ enum { value = false }; };
|
||||
template<class T>
|
||||
struct _hb_is_iterable<T, hb_bool_tt<(bool) sizeof (hb_declval<T> ().iter ())> >
|
||||
{ enum { value = true }; };
|
||||
template<class T>
|
||||
struct hb_is_iterable { enum { value = _hb_is_iterable<T, hb_true_t>::value }; };
|
||||
|
||||
#define hb_is_iterable(Iterable) hb_is_iterable<Iterable>::value
|
||||
|
||||
|
||||
/*
|
||||
* Algorithms operating on iterators or iteratables.
|
||||
*/
|
||||
|
||||
template <typename C, typename V> inline void
|
||||
hb_fill (const C& c, const V &v)
|
||||
|
|
|
@ -35,12 +35,17 @@
|
|||
*/
|
||||
|
||||
|
||||
template <typename T> static T hb_declval ();
|
||||
|
||||
|
||||
/* Void! For when we need a expression-type of void. */
|
||||
struct hb_void_t { typedef void value; };
|
||||
|
||||
struct hb_true_t { enum { value = true }; };
|
||||
struct hb_false_t { enum { value = false }; };
|
||||
|
||||
/* Bool! For when we need to evaluate type-dependent expressions
|
||||
* in a template argument. */
|
||||
template <bool b> struct hb_bool_tt { enum { value = b }; };
|
||||
typedef hb_bool_tt<true> hb_true_t;
|
||||
typedef hb_bool_tt<false> hb_false_t;
|
||||
|
||||
|
||||
template<bool B, class T = void>
|
||||
|
@ -49,7 +54,7 @@ struct hb_enable_if {};
|
|||
template<class T>
|
||||
struct hb_enable_if<true, T> { typedef T type; };
|
||||
|
||||
#define hb_enable_if(Cond) hb_enable_if<Code>::type* = nullptr
|
||||
#define hb_enable_if(Cond) typename hb_enable_if<Cond>::type* = nullptr
|
||||
#define hb_enable_if_t(Type, Cond) hb_enable_if<(Cond), Type>::type
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#define HB_NULL_HH
|
||||
|
||||
#include "hb.hh"
|
||||
#include "hb-meta.hh"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -45,18 +46,16 @@
|
|||
* https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol
|
||||
*/
|
||||
|
||||
template<bool> struct _hb_bool_type {};
|
||||
|
||||
template <typename T, typename B>
|
||||
struct _hb_null_size
|
||||
{ enum { value = sizeof (T) }; };
|
||||
template <typename T>
|
||||
struct _hb_null_size<T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
|
||||
struct _hb_null_size<T, hb_bool_tt<(bool) (1 + (unsigned int) T::min_size)> >
|
||||
{ enum { value = T::null_size }; };
|
||||
|
||||
template <typename T>
|
||||
struct hb_null_size
|
||||
{ enum { value = _hb_null_size<T, _hb_bool_type<true> >::value }; };
|
||||
{ enum { value = _hb_null_size<T, hb_true_t>::value }; };
|
||||
#define hb_null_size(T) hb_null_size<T>::value
|
||||
|
||||
/* These doesn't belong here, but since is copy/paste from above, put it here. */
|
||||
|
@ -68,12 +67,12 @@ template <typename T, typename B>
|
|||
struct _hb_static_size
|
||||
{ enum { value = sizeof (T) }; };
|
||||
template <typename T>
|
||||
struct _hb_static_size<T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
|
||||
struct _hb_static_size<T, hb_bool_tt<(bool) (1 + (unsigned int) T::min_size)> >
|
||||
{ enum { value = T::static_size }; };
|
||||
|
||||
template <typename T>
|
||||
struct hb_static_size
|
||||
{ enum { value = _hb_static_size<T, _hb_bool_type<true> >::value }; };
|
||||
{ enum { value = _hb_static_size<T, hb_true_t>::value }; };
|
||||
#define hb_static_size(T) hb_static_size<T>::value
|
||||
|
||||
|
||||
|
@ -85,15 +84,15 @@ template <typename T, typename V, typename B>
|
|||
struct _hb_assign
|
||||
{ static inline void value (T &o, const V v) { o = v; } };
|
||||
template <typename T, typename V>
|
||||
struct _hb_assign<T, V, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
|
||||
struct _hb_assign<T, V, hb_bool_tt<(bool) (1 + (unsigned int) T::min_size)> >
|
||||
{ static inline void value (T &o, const V v) { o.set (v); } };
|
||||
template <typename T>
|
||||
struct _hb_assign<T, T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
|
||||
struct _hb_assign<T, T, hb_bool_tt<(bool) (1 + (unsigned int) T::min_size)> >
|
||||
{ static inline void value (T &o, const T v) { o = v; } };
|
||||
|
||||
template <typename T, typename V>
|
||||
static inline void hb_assign (T &o, const V v)
|
||||
{ _hb_assign<T, V, _hb_bool_type<true> >::value (o, v); }
|
||||
{ _hb_assign<T, V, hb_true_t>::value (o, v); }
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -556,8 +556,10 @@ struct ArrayOf
|
|||
if (unlikely (!c->extend (*this))) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
template <typename Iter>
|
||||
bool serialize (hb_serialize_context_t *c, const hb_iter_t<Iter>& items)
|
||||
template <typename Iterable,
|
||||
hb_enable_if (hb_is_iterable (Iterable))>
|
||||
bool serialize (hb_serialize_context_t *c,
|
||||
const Iterable& items)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
unsigned count = items.len ();
|
||||
|
|
|
@ -630,7 +630,7 @@ template <typename T> struct hb_remove_pointer<T *> { typedef T value; };
|
|||
#include "hb-atomic.hh"
|
||||
#include "hb-meta.hh"
|
||||
#include "hb-mutex.hh"
|
||||
#include "hb-null.hh"
|
||||
#include "hb-null.hh" // Requires: hb-meta
|
||||
#include "hb-dsalgs.hh" // Requires: hb-null
|
||||
#include "hb-iter.hh" // Requires: hb-dsalgs hb-meta hb-null
|
||||
#include "hb-debug.hh" // Requires: hb-atomic hb-dsalgs
|
||||
|
|
Loading…
Reference in New Issue