1372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko/*
2372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko * Copyright (C) 2016 The Android Open Source Project
3372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko *
4372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko * Licensed under the Apache License, Version 2.0 (the "License");
5372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko * you may not use this file except in compliance with the License.
6372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko * You may obtain a copy of the License at
7372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko *
8372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko *      http://www.apache.org/licenses/LICENSE-2.0
9372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko *
10372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko * Unless required by applicable law or agreed to in writing, software
11372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko * distributed under the License is distributed on an "AS IS" BASIS,
12372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko * See the License for the specific language governing permissions and
14372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko * limitations under the License.
15372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko */
16372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
17372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko#include <algorithm>
18372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko#include <forward_list>
19372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko#include <list>
20372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko#include <type_traits>
21372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko#include <vector>
22372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
23372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko#include "gtest/gtest.h"
24372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
25d9c90373d640a5e08072cf469c372e24a8c0fc35David Brazdil#include "base/transform_iterator.h"
26372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
27372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Markonamespace art {
28372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
29372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Markonamespace {  // anonymous namespace
30372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
31372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Markostruct ValueHolder {
32372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  // Deliberately not explicit.
33372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ValueHolder(int v) : value(v) { }  // NOLINT
34372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  int value;
35372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko};
36372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
37372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Markobool operator==(const ValueHolder& lhs, const ValueHolder& rhs) {
38372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  return lhs.value == rhs.value;
39372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}
40372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
41372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}  // anonymous namespace
42372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
43372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir MarkoTEST(TransformIterator, VectorAdd1) {
445573c37e795668eca81a8488078f798d977685c3Igor Murashkin  auto add1 = [](const ValueHolder& h) { return h.value + 1; };
45372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<ValueHolder> input({ 1, 7, 3, 8 });
46372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<int> output;
47372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
48372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_titer = decltype(MakeTransformIterator(input.begin(), add1));
49372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
50372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_titer::iterator_category>::value, "category");
51372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_titer::value_type>::value, "value_type");
52372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<vector_titer, vector_titer::pointer>::value, "pointer");
53372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_titer::reference>::value, "reference");
54372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
55372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_ctiter = decltype(MakeTransformIterator(input.cbegin(), add1));
56372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
57372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_ctiter::iterator_category>::value, "category");
58372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_ctiter::value_type>::value, "value_type");
59372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<vector_ctiter, vector_ctiter::pointer>::value, "pointer");
60372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_ctiter::reference>::value, "reference");
61372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
62372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_rtiter = decltype(MakeTransformIterator(input.rbegin(), add1));
63372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
64372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_rtiter::iterator_category>::value, "category");
65372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_rtiter::value_type>::value, "value_type");
66372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<vector_rtiter, vector_rtiter::pointer>::value, "pointer");
67372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_rtiter::reference>::value, "reference");
68372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
69372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_crtiter = decltype(MakeTransformIterator(input.crbegin(), add1));
70372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
71372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_crtiter::iterator_category>::value, "category");
72372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_crtiter::value_type>::value, "value_type");
73372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<vector_crtiter, vector_crtiter::pointer>::value, "pointer");
74372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_crtiter::reference>::value, "reference");
75372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
76372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.begin(), add1),
77372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.end(), add1),
78372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
79372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 2, 8, 4, 9 }), output);
80372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
81372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
82372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.cbegin(), add1),
83372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.cend(), add1),
84372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
85372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 2, 8, 4, 9 }), output);
86372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
87372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
88372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.rbegin(), add1),
89372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.rend(), add1),
90372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
91372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 9, 4, 8, 2 }), output);
92372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
93372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
94372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.crbegin(), add1),
95372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.crend(), add1),
96372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
97372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 9, 4, 8, 2 }), output);
98372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
99372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
100372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  for (size_t i = 0; i != input.size(); ++i) {
101372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value + 1, MakeTransformIterator(input.begin(), add1)[i]);
102372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value + 1, MakeTransformIterator(input.cbegin(), add1)[i]);
103372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_rbegin = static_cast<ptrdiff_t>(input.size() - i - 1u);
104372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value + 1, MakeTransformIterator(input.rbegin(), add1)[index_from_rbegin]);
105372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value + 1, MakeTransformIterator(input.crbegin(), add1)[index_from_rbegin]);
106372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_end = -static_cast<ptrdiff_t>(input.size() - i);
107372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value + 1, MakeTransformIterator(input.end(), add1)[index_from_end]);
108372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value + 1, MakeTransformIterator(input.cend(), add1)[index_from_end]);
109372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_rend = -1 - static_cast<ptrdiff_t>(i);
110372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value + 1, MakeTransformIterator(input.rend(), add1)[index_from_rend]);
111372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value + 1, MakeTransformIterator(input.crend(), add1)[index_from_rend]);
112372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
113372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.begin(), add1) + i,
114372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.begin() + i, add1));
115372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.cbegin(), add1) + i,
116372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.cbegin() + i, add1));
117372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.rbegin(), add1) + i,
118372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.rbegin() + i, add1));
119372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.crbegin(), add1) + i,
120372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.crbegin() + i, add1));
121372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.end(), add1) - i,
122372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.end() - i, add1));
123372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.cend(), add1) - i,
124372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.cend() - i, add1));
125372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.rend(), add1) - i,
126372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.rend() - i, add1));
127372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.crend(), add1) - i,
128372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.crend() - i, add1));
129372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  }
130372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(input.end(),
131372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            (MakeTransformIterator(input.begin(), add1) + input.size()).base());
132372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(MakeTransformIterator(input.end(), add1) - MakeTransformIterator(input.begin(), add1),
133372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            static_cast<ptrdiff_t>(input.size()));
134372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
135372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  // Test iterator->const_iterator conversion and comparison.
136372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  auto it = MakeTransformIterator(input.begin(), add1);
137372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  decltype(MakeTransformIterator(input.cbegin(), add1)) cit = it;
138372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(!std::is_same<decltype(it), decltype(cit)>::value, "Types must be different");
139372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(it, cit);
140372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  auto rit = MakeTransformIterator(input.rbegin(), add1);
141372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  decltype(MakeTransformIterator(input.crbegin(), add1)) crit(rit);
142372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(!std::is_same<decltype(rit), decltype(crit)>::value, "Types must be different");
143372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(rit, crit);
144372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}
145372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
146372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir MarkoTEST(TransformIterator, ListSub1) {
1475573c37e795668eca81a8488078f798d977685c3Igor Murashkin  auto sub1 = [](const ValueHolder& h) { return h.value - 1; };
148372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::list<ValueHolder> input({ 2, 3, 5, 7, 11 });
149372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<int> output;
150372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
151372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using list_titer = decltype(MakeTransformIterator(input.begin(), sub1));
152372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::bidirectional_iterator_tag,
153372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             list_titer::iterator_category>::value, "category");
154372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, list_titer::value_type>::value, "value_type");
155372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<list_titer, list_titer::pointer>::value, "pointer");
156372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, list_titer::reference>::value, "reference");
157372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
158372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using list_ctiter = decltype(MakeTransformIterator(input.cbegin(), sub1));
159372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::bidirectional_iterator_tag,
160372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             list_ctiter::iterator_category>::value, "category");
161372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, list_ctiter::value_type>::value, "value_type");
162372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<list_ctiter, list_ctiter::pointer>::value, "pointer");
163372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, list_ctiter::reference>::value, "reference");
164372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
165372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using list_rtiter = decltype(MakeTransformIterator(input.rbegin(), sub1));
166372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::bidirectional_iterator_tag,
167372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             list_rtiter::iterator_category>::value, "category");
168372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, list_rtiter::value_type>::value, "value_type");
169372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<list_rtiter, list_rtiter::pointer>::value, "pointer");
170372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, list_rtiter::reference>::value, "reference");
171372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
172372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using list_crtiter = decltype(MakeTransformIterator(input.crbegin(), sub1));
173372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::bidirectional_iterator_tag,
174372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             list_crtiter::iterator_category>::value, "category");
175372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, list_crtiter::value_type>::value, "value_type");
176372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<list_crtiter, list_crtiter::pointer>::value, "pointer");
177372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, list_crtiter::reference>::value, "reference");
178372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
179372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.begin(), sub1),
180372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.end(), sub1),
181372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
182372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 1, 2, 4, 6, 10 }), output);
183372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
184372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
185372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.cbegin(), sub1),
186372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.cend(), sub1),
187372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
188372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 1, 2, 4, 6, 10 }), output);
189372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
190372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
191372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.rbegin(), sub1),
192372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.rend(), sub1),
193372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
194372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 10, 6, 4, 2, 1 }), output);
195372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
196372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
197372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.crbegin(), sub1),
198372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.crend(), sub1),
199372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
200372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 10, 6, 4, 2, 1  }), output);
201372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
202372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
203372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  // Test iterator->const_iterator conversion and comparison.
204372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  auto it = MakeTransformIterator(input.begin(), sub1);
205372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  decltype(MakeTransformIterator(input.cbegin(), sub1)) cit = it;
206372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(!std::is_same<decltype(it), decltype(cit)>::value, "Types must be different");
207372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(it, cit);
208372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}
209372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
210372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir MarkoTEST(TransformIterator, ForwardListSub1) {
2115573c37e795668eca81a8488078f798d977685c3Igor Murashkin  auto mul3 = [](const ValueHolder& h) { return h.value * 3; };
212372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::forward_list<ValueHolder> input({ 1, 1, 2, 3, 5, 8 });
213372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<int> output;
214372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
215372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using flist_titer = decltype(MakeTransformIterator(input.begin(), mul3));
216372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::forward_iterator_tag,
217372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             flist_titer::iterator_category>::value, "category");
218372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, flist_titer::value_type>::value, "value_type");
219372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<flist_titer, flist_titer::pointer>::value, "pointer");
220372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, flist_titer::reference>::value, "reference");
221372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
222372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using flist_ctiter = decltype(MakeTransformIterator(input.cbegin(), mul3));
223372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::forward_iterator_tag,
224372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             flist_ctiter::iterator_category>::value, "category");
225372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, flist_ctiter::value_type>::value, "value_type");
226372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<flist_ctiter, flist_ctiter::pointer>::value, "pointer");
227372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, flist_ctiter::reference>::value, "reference");
228372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
229372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.begin(), mul3),
230372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.end(), mul3),
231372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
232372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 3, 3, 6, 9, 15, 24 }), output);
233372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
234372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
235372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.cbegin(), mul3),
236372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.cend(), mul3),
237372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
238372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 3, 3, 6, 9, 15, 24 }), output);
239372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
240372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
241372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  // Test iterator->const_iterator conversion and comparison.
242372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  auto it = MakeTransformIterator(input.begin(), mul3);
243372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  decltype(MakeTransformIterator(input.cbegin(), mul3)) cit = it;
244372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(!std::is_same<decltype(it), decltype(cit)>::value, "Types must be different");
245372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(it, cit);
246372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}
247372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
248372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir MarkoTEST(TransformIterator, VectorConstReference) {
2495573c37e795668eca81a8488078f798d977685c3Igor Murashkin  auto ref = [](const ValueHolder& h) -> const int& { return h.value; };
250372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<ValueHolder> input({ 7, 3, 1, 2, 4, 8 });
251372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<int> output;
252372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
253372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_titer = decltype(MakeTransformIterator(input.begin(), ref));
254372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
255372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_titer::iterator_category>::value, "category");
256372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_titer::value_type>::value, "value_type");
257372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int*, vector_titer::pointer>::value, "pointer");
258372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int&, vector_titer::reference>::value, "reference");
259372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
260372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_ctiter = decltype(MakeTransformIterator(input.cbegin(), ref));
261372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
262372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_ctiter::iterator_category>::value, "category");
263372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_ctiter::value_type>::value, "value_type");
264372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int*, vector_ctiter::pointer>::value, "pointer");
265372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int&, vector_ctiter::reference>::value, "reference");
266372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
267372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_rtiter = decltype(MakeTransformIterator(input.rbegin(), ref));
268372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
269372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_rtiter::iterator_category>::value, "category");
270372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_rtiter::value_type>::value, "value_type");
271372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int*, vector_rtiter::pointer>::value, "pointer");
272372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int&, vector_rtiter::reference>::value, "reference");
273372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
274372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_crtiter = decltype(MakeTransformIterator(input.crbegin(), ref));
275372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
276372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_crtiter::iterator_category>::value, "category");
277372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_crtiter::value_type>::value, "value_type");
278372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int*, vector_crtiter::pointer>::value, "pointer");
279372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int&, vector_crtiter::reference>::value, "reference");
280372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
281372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.begin(), ref),
282372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.end(), ref),
283372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
284372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 7, 3, 1, 2, 4, 8 }), output);
285372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
286372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
287372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.cbegin(), ref),
288372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.cend(), ref),
289372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
290372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 7, 3, 1, 2, 4, 8 }), output);
291372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
292372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
293372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.rbegin(), ref),
294372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.rend(), ref),
295372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
296372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 8, 4, 2, 1, 3, 7 }), output);
297372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
298372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
299372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.crbegin(), ref),
300372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.crend(), ref),
301372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
302372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 8, 4, 2, 1, 3, 7 }), output);
303372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
304372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
305372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  for (size_t i = 0; i != input.size(); ++i) {
306372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.begin(), ref)[i]);
307372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.cbegin(), ref)[i]);
308372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_rbegin = static_cast<ptrdiff_t>(input.size() - i - 1u);
309372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.rbegin(), ref)[index_from_rbegin]);
310372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.crbegin(), ref)[index_from_rbegin]);
311372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_end = -static_cast<ptrdiff_t>(input.size() - i);
312372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.end(), ref)[index_from_end]);
313372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.cend(), ref)[index_from_end]);
314372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_rend = -1 - static_cast<ptrdiff_t>(i);
315372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.rend(), ref)[index_from_rend]);
316372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.crend(), ref)[index_from_rend]);
317372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
318372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.begin(), ref) + i,
319372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.begin() + i, ref));
320372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.cbegin(), ref) + i,
321372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.cbegin() + i, ref));
322372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.rbegin(), ref) + i,
323372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.rbegin() + i, ref));
324372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.crbegin(), ref) + i,
325372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.crbegin() + i, ref));
326372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.end(), ref) - i,
327372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.end() - i, ref));
328372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.cend(), ref) - i,
329372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.cend() - i, ref));
330372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.rend(), ref) - i,
331372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.rend() - i, ref));
332372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.crend(), ref) - i,
333372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.crend() - i, ref));
334372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  }
335372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(input.end(),
336372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            (MakeTransformIterator(input.begin(), ref) + input.size()).base());
337372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(MakeTransformIterator(input.end(), ref) - MakeTransformIterator(input.begin(), ref),
338372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            static_cast<ptrdiff_t>(input.size()));
339372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}
340372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
341372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir MarkoTEST(TransformIterator, VectorNonConstReference) {
3425573c37e795668eca81a8488078f798d977685c3Igor Murashkin  auto ref = [](ValueHolder& h) -> int& { return h.value; };
343372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<ValueHolder> input({ 7, 3, 1, 2, 4, 8 });
344372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<int> output;
345372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
346372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_titer = decltype(MakeTransformIterator(input.begin(), ref));
347372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
348372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_titer::iterator_category>::value, "category");
349372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_titer::value_type>::value, "value_type");
350372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int*, vector_titer::pointer>::value, "pointer");
351372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int&, vector_titer::reference>::value, "reference");
352372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
353372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_rtiter = decltype(MakeTransformIterator(input.rbegin(), ref));
354372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
355372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_rtiter::iterator_category>::value, "category");
356372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_rtiter::value_type>::value, "value_type");
357372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int*, vector_rtiter::pointer>::value, "pointer");
358372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int&, vector_rtiter::reference>::value, "reference");
359372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
360372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.begin(), ref),
361372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.end(), ref),
362372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
363372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 7, 3, 1, 2, 4, 8 }), output);
364372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
365372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
366372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.rbegin(), ref),
367372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.rend(), ref),
368372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
369372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 8, 4, 2, 1, 3, 7 }), output);
370372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
371372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
372372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  for (size_t i = 0; i != input.size(); ++i) {
373372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.begin(), ref)[i]);
374372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_rbegin = static_cast<ptrdiff_t>(input.size() - i - 1u);
375372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.rbegin(), ref)[index_from_rbegin]);
376372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_end = -static_cast<ptrdiff_t>(input.size() - i);
377372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.end(), ref)[index_from_end]);
378372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_rend = -1 - static_cast<ptrdiff_t>(i);
379372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.rend(), ref)[index_from_rend]);
380372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
381372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.begin(), ref) + i,
382372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.begin() + i, ref));
383372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.rbegin(), ref) + i,
384372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.rbegin() + i, ref));
385372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.end(), ref) - i,
386372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.end() - i, ref));
387372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.rend(), ref) - i,
388372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.rend() - i, ref));
389372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  }
390372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(input.end(),
391372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            (MakeTransformIterator(input.begin(), ref) + input.size()).base());
392372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(MakeTransformIterator(input.end(), ref) - MakeTransformIterator(input.begin(), ref),
393372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            static_cast<ptrdiff_t>(input.size()));
394372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
395372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  // Test writing through the transform iterator.
396372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::list<int> transform_input({ 1, -1, 2, -2, 3, -3 });
397372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<ValueHolder> transformed(transform_input.size(), 0);
398372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::transform(transform_input.begin(),
399372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                 transform_input.end(),
400372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                 MakeTransformIterator(transformed.begin(), ref),
401372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                 [](int v) { return -2 * v; });
402372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<ValueHolder>({ -2, 2, -4, 4, -6, 6 }), transformed);
403372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}
404372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
405372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir MarkoTEST(TransformIterator, VectorConstAndNonConstReference) {
406372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  struct Ref {
407372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    int& operator()(ValueHolder& h) const { return h.value; }
408372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    const int& operator()(const ValueHolder& h) const { return h.value; }
409372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  };
410372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  Ref ref;
411372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<ValueHolder> input({ 7, 3, 1, 2, 4, 8 });
412372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<int> output;
413372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
414372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_titer = decltype(MakeTransformIterator(input.begin(), ref));
415372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
416372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_titer::iterator_category>::value, "category");
417372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_titer::value_type>::value, "value_type");
418372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int*, vector_titer::pointer>::value, "pointer");
419372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int&, vector_titer::reference>::value, "reference");
420372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
421372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_ctiter = decltype(MakeTransformIterator(input.cbegin(), ref));
422372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
423372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_ctiter::iterator_category>::value, "category");
424372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  // static_assert(std::is_same<int, vector_ctiter::value_type>::value, "value_type");
425372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int*, vector_ctiter::pointer>::value, "pointer");
426372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int&, vector_ctiter::reference>::value, "reference");
427372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
428372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_rtiter = decltype(MakeTransformIterator(input.rbegin(), ref));
429372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
430372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_rtiter::iterator_category>::value, "category");
431372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int, vector_rtiter::value_type>::value, "value_type");
432372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int*, vector_rtiter::pointer>::value, "pointer");
433372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<int&, vector_rtiter::reference>::value, "reference");
434372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
435372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  using vector_crtiter = decltype(MakeTransformIterator(input.crbegin(), ref));
436372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<std::random_access_iterator_tag,
437372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                             vector_crtiter::iterator_category>::value, "category");
438372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  // static_assert(std::is_same<int, vector_crtiter::value_type>::value, "value_type");
439372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int*, vector_crtiter::pointer>::value, "pointer");
440372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(std::is_same<const int&, vector_crtiter::reference>::value, "reference");
441372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
442372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.begin(), ref),
443372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.end(), ref),
444372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
445372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 7, 3, 1, 2, 4, 8 }), output);
446372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
447372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
448372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.cbegin(), ref),
449372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.cend(), ref),
450372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
451372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 7, 3, 1, 2, 4, 8 }), output);
452372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
453372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
454372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.rbegin(), ref),
455372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.rend(), ref),
456372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
457372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 8, 4, 2, 1, 3, 7 }), output);
458372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
459372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
460372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::copy(MakeTransformIterator(input.crbegin(), ref),
461372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            MakeTransformIterator(input.crend(), ref),
462372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            std::back_inserter(output));
463372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<int>({ 8, 4, 2, 1, 3, 7 }), output);
464372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  output.clear();
465372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
466372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  for (size_t i = 0; i != input.size(); ++i) {
467372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.begin(), ref)[i]);
468372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.cbegin(), ref)[i]);
469372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_rbegin = static_cast<ptrdiff_t>(input.size() - i - 1u);
470372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.rbegin(), ref)[index_from_rbegin]);
471372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.crbegin(), ref)[index_from_rbegin]);
472372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_end = -static_cast<ptrdiff_t>(input.size() - i);
473372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.end(), ref)[index_from_end]);
474372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.cend(), ref)[index_from_end]);
475372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ptrdiff_t index_from_rend = -1 - static_cast<ptrdiff_t>(i);
476372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.rend(), ref)[index_from_rend]);
477372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(input[i].value, MakeTransformIterator(input.crend(), ref)[index_from_rend]);
478372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
479372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.begin(), ref) + i,
480372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.begin() + i, ref));
481372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.cbegin(), ref) + i,
482372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.cbegin() + i, ref));
483372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.rbegin(), ref) + i,
484372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.rbegin() + i, ref));
485372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.crbegin(), ref) + i,
486372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.crbegin() + i, ref));
487372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.end(), ref) - i,
488372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.end() - i, ref));
489372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.cend(), ref) - i,
490372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.cend() - i, ref));
491372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.rend(), ref) - i,
492372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.rend() - i, ref));
493372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    ASSERT_EQ(MakeTransformIterator(input.crend(), ref) - i,
494372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko              MakeTransformIterator(input.crend() - i, ref));
495372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  }
496372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(input.end(),
497372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            (MakeTransformIterator(input.begin(), ref) + input.size()).base());
498372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(MakeTransformIterator(input.end(), ref) - MakeTransformIterator(input.begin(), ref),
499372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko            static_cast<ptrdiff_t>(input.size()));
500372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
501372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  // Test iterator->const_iterator conversion and comparison.
502372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  auto it = MakeTransformIterator(input.begin(), ref);
503372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  decltype(MakeTransformIterator(input.cbegin(), ref)) cit = it;
504372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(!std::is_same<decltype(it), decltype(cit)>::value, "Types must be different");
505372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(it, cit);
506372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  auto rit = MakeTransformIterator(input.rbegin(), ref);
507372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  decltype(MakeTransformIterator(input.crbegin(), ref)) crit(rit);
508372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  static_assert(!std::is_same<decltype(rit), decltype(crit)>::value, "Types must be different");
509372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(rit, crit);
510372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
511372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  // Test writing through the transform iterator.
512372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::list<int> transform_input({ 42, 73, 11, 17 });
513372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<ValueHolder> transformed(transform_input.size(), 0);
514372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::transform(transform_input.begin(),
515372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                 transform_input.end(),
516372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                 MakeTransformIterator(transformed.begin(), ref),
517372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko                 [](int v) { return -v; });
518372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<ValueHolder>({ -42, -73, -11, -17 }), transformed);
519372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}
520372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
521372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir MarkoTEST(TransformIterator, TransformRange) {
5225573c37e795668eca81a8488078f798d977685c3Igor Murashkin  auto ref = [](ValueHolder& h) -> int& { return h.value; };
523372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  std::vector<ValueHolder> data({ 1, 0, 1, 3, 1, 0 });
524372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
525372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  for (int& v : MakeTransformRange(data, ref)) {
526372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko    v += 11;
527372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  }
528372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko  ASSERT_EQ(std::vector<ValueHolder>({ 12, 11, 12, 14, 12, 11 }), data);
529372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}
530372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko
531372f10e5b0b34e2bb6e2b79aeba6c441e14afd1fVladimir Marko}  // namespace art
532