5 #ifndef VCCC_ITERATOR_ADVANCE_HPP_
6 #define VCCC_ITERATOR_ADVANCE_HPP_
26 struct advance_niebloid;
27 using vccc::detail::conditional_tag;
28 using vccc::detail::tag_1;
29 using vccc::detail::tag_2;
30 using vccc::detail::tag_3;
31 using vccc::detail::tag_else;
34 using advance_n_tag = conditional_tag<random_access_iterator<I>, bidirectional_iterator<I>>;
37 constexpr
void advance_n(I& i, iter_difference_t<I> n, tag_1 ) {
42 constexpr
void advance_n(I& i, iter_difference_t<I> n, tag_2 ) {
55 constexpr
void advance_n(I& i, iter_difference_t<I> n, tag_else) {
62 template<
typename I,
typename S>
63 struct advance_bound_check_impl : conjunction<input_or_output_iterator<I>, sentinel_for<S, I>> {};
65 template<
typename I,
typename S,
bool = has_
typename_type<iter_difference<I>>::value >
66 struct advance_bound_check : conjunction< negation<std::is_same<iter_difference_t<I>, S>>,
67 advance_bound_check_impl<I, S> > {};
68 template<
typename I,
typename S>
69 struct advance_bound_check<I, S, false> : advance_bound_check_impl<I, S> {};
71 template<
typename I,
typename S>
72 using advance_bound_tag = conditional_tag<assignable_from<I&, S>, sized_sentinel_for<S, I>>;
74 template<
typename I,
typename S>
75 constexpr
void advance_bound(I& i, S bound, tag_1 ) {
79 template<
typename I,
typename S>
80 constexpr
void advance_bound(I& i, S bound, tag_2 );
82 template<
typename I,
typename S>
83 constexpr
void advance_bound(I& i, S bound, tag_else) {
89 template<
typename I,
typename S>
90 using advance_mixed_tag = conditional_tag<sized_sentinel_for<S, I>, bidirectional_iterator<I>>;
92 template<
typename I,
typename S>
93 constexpr iter_difference_t<I>
94 advance_mixed(I& i, iter_difference_t<I> n, S bound, tag_1 );
96 template<
typename I,
typename S>
97 constexpr iter_difference_t<I>
98 advance_mixed(I& i, iter_difference_t<I> n, S bound, tag_2 ) {
99 while (n > 0 && i != bound) {
104 while (n < 0 && i != bound) {
112 template<
typename I,
typename S>
113 constexpr iter_difference_t<I>
114 advance_mixed(I& i, iter_difference_t<I> n, S bound, tag_else) {
115 while (n > 0 && i != bound) {
123 struct advance_niebloid {
126 operator()(I& i, iter_difference_t<I> n)
const {
127 advance_n(i, n, advance_n_tag<I>{});
132 template<
typename I,
typename S>
134 operator()(I& i, S bound)
const {
135 advance_bound(i, bound, advance_bound_tag<I, S>{});
139 template<
typename I,
typename S, std::enable_if_t<conjunction<
140 input_or_output_iterator<I>,
143 constexpr iter_difference_t<I>
144 operator()(I& i, iter_difference_t<I> n, S bound)
const {
145 return advance_mixed(i, n, bound, advance_mixed_tag<I, S>{});
164 using namespace niebloid;
168 template<
typename I,
typename S>
169 constexpr
void advance_bound(I& i, S bound, tag_2 ) {
173 template<
typename I,
typename S>
174 constexpr iter_difference_t<I>
175 advance_mixed(I& i, iter_difference_t<I> n, S bound, tag_1 ) {
176 const iter_difference_t<I> d = bound - i;
177 if ((n < 0 && n <= d) || (n > 0 && n >= d)) {
constexpr VCCC_INLINE_OR_STATIC detail::advance_niebloid advance
Definition: advance.hpp:158
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35