[iter/meta] Implement is_iterator
Removes use of auto type deduction again, which was not supported on many bots.
This commit is contained in:
parent
8570da1d74
commit
df138da2e6
|
@ -55,6 +55,7 @@ struct hb_iter_t
|
||||||
typedef Iter iter_t;
|
typedef Iter iter_t;
|
||||||
typedef Item item_t;
|
typedef Item item_t;
|
||||||
enum { item_size = hb_static_size (Item) };
|
enum { item_size = hb_static_size (Item) };
|
||||||
|
enum { is_iter = true };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
|
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
|
||||||
|
@ -88,6 +89,10 @@ struct hb_iter_t
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HB_ITER_USING(Name) \
|
#define HB_ITER_USING(Name) \
|
||||||
|
using typename Name::iter_t; \
|
||||||
|
using typename Name::item_t; \
|
||||||
|
using Name::item_size; \
|
||||||
|
using Name::is_iter; \
|
||||||
using Name::iter; \
|
using Name::iter; \
|
||||||
using Name::operator bool; \
|
using Name::operator bool; \
|
||||||
using Name::len; \
|
using Name::len; \
|
||||||
|
@ -154,18 +159,49 @@ struct hb_iter_mixin_t
|
||||||
* Meta-programming predicates.
|
* Meta-programming predicates.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<class T, typename B>
|
/* hb_is_iterable() */
|
||||||
|
|
||||||
|
template<typename T, typename B>
|
||||||
struct _hb_is_iterable
|
struct _hb_is_iterable
|
||||||
{ enum { value = false }; };
|
{ enum { value = false }; };
|
||||||
template<class T>
|
template<typename T>
|
||||||
struct _hb_is_iterable<T, hb_bool_tt<true || sizeof (hb_declval<T> ().iter ())> >
|
struct _hb_is_iterable<T, hb_bool_tt<true || sizeof (hb_declval<T> ().iter ())> >
|
||||||
{ enum { value = true }; };
|
{ enum { value = true }; };
|
||||||
|
|
||||||
template<class T>
|
template<typename T>
|
||||||
struct hb_is_iterable { enum { value = _hb_is_iterable<T, hb_true_t>::value }; };
|
struct hb_is_iterable { enum { value = _hb_is_iterable<T, hb_true_t>::value }; };
|
||||||
#define hb_is_iterable(Iterable) hb_is_iterable<Iterable>::value
|
#define hb_is_iterable(Iterable) hb_is_iterable<Iterable>::value
|
||||||
|
|
||||||
|
|
||||||
|
/* hb_is_iterator() */
|
||||||
|
|
||||||
|
/* The following SFINAE fails to match template parameters to hb_iter_t<>.
|
||||||
|
* As such, just check for member is_iter being there. */
|
||||||
|
# if 0
|
||||||
|
template<typename T = void> char
|
||||||
|
_hb_is_iterator (T *) {};
|
||||||
|
template<typename Iter, typename Item> int
|
||||||
|
_hb_is_iterator (hb_iter_t<Iter, Item> *) {};
|
||||||
|
static_assert (sizeof (char) != sizeof (int), "");
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct hb_is_iterator { enum {
|
||||||
|
value = sizeof (int) == sizeof (_hb_is_iterator (hb_declval<T*> ()))
|
||||||
|
}; };
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T, typename B>
|
||||||
|
struct _hb_is_iterator
|
||||||
|
{ enum { value = false }; };
|
||||||
|
template<typename T>
|
||||||
|
struct _hb_is_iterator<T, hb_bool_tt<true || sizeof (T::is_iter)> >
|
||||||
|
{ enum { value = true }; };
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct hb_is_iterator { enum { value = _hb_is_iterator<T, hb_true_t>::value }; };
|
||||||
|
#define hb_is_iterator(Iterator) hb_is_iterator<Iterator>::value
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Algorithms operating on iterators or iteratables.
|
* Algorithms operating on iterators or iteratables.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,10 +48,10 @@ typedef hb_bool_tt<true> hb_true_t;
|
||||||
typedef hb_bool_tt<false> hb_false_t;
|
typedef hb_bool_tt<false> hb_false_t;
|
||||||
|
|
||||||
|
|
||||||
template<bool B, class T = void>
|
template<bool B, typename T = void>
|
||||||
struct hb_enable_if {};
|
struct hb_enable_if {};
|
||||||
|
|
||||||
template<class T>
|
template<typename T>
|
||||||
struct hb_enable_if<true, T> { typedef T type; };
|
struct hb_enable_if<true, T> { typedef T type; };
|
||||||
|
|
||||||
#define hb_enable_if(Cond) typename hb_enable_if<Cond>::type* = nullptr
|
#define hb_enable_if(Cond) typename hb_enable_if<Cond>::type* = nullptr
|
||||||
|
|
|
@ -552,17 +552,18 @@ struct ArrayOf
|
||||||
if (unlikely (!c->extend (*this))) return_trace (false);
|
if (unlikely (!c->extend (*this))) return_trace (false);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
template <typename Iterable,
|
template <typename Iterator,
|
||||||
hb_enable_if (hb_is_iterable (Iterable))>
|
hb_enable_if (hb_is_iterator (Iterator))>
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
const Iterable& items)
|
Iterator items)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
unsigned count = items.len ();
|
unsigned count = items.len ();
|
||||||
if (unlikely (!serialize (c, count))) return_trace (false);
|
if (unlikely (!serialize (c, count))) return_trace (false);
|
||||||
auto iter = items.iter ();
|
/* TODO Umm. Just exhaust the iterator instead? Being extra
|
||||||
for (unsigned i = 0; i < count; i++, iter++)
|
* cautious right now.. */
|
||||||
hb_assign (arrayZ[i], *iter);
|
for (unsigned i = 0; i < count; i++, items++)
|
||||||
|
hb_assign (arrayZ[i], *items);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue