00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/utility/utility.h"
00016
00017 #include <sstream>
00018 #include <string>
00019 #include <tuple>
00020 #include <type_traits>
00021 #include <vector>
00022
00023 #include "gmock/gmock.h"
00024 #include "gtest/gtest.h"
00025 #include "absl/base/attributes.h"
00026 #include "absl/memory/memory.h"
00027 #include "absl/strings/str_cat.h"
00028
00029 namespace {
00030
00031 #ifdef _MSC_VER
00032
00033
00034
00035
00036
00037
00038 #pragma warning( push )
00039 #pragma warning( disable : 4503 ) // decorated name length exceeded
00040 #pragma warning( disable : 4101 ) // unreferenced local variable
00041 #endif // _MSC_VER
00042
00043 using ::testing::ElementsAre;
00044 using ::testing::Pointee;
00045 using ::testing::StaticAssertTypeEq;
00046
00047 TEST(IntegerSequenceTest, ValueType) {
00048 StaticAssertTypeEq<int, absl::integer_sequence<int>::value_type>();
00049 StaticAssertTypeEq<char, absl::integer_sequence<char>::value_type>();
00050 }
00051
00052 TEST(IntegerSequenceTest, Size) {
00053 EXPECT_EQ(0, (absl::integer_sequence<int>::size()));
00054 EXPECT_EQ(1, (absl::integer_sequence<int, 0>::size()));
00055 EXPECT_EQ(1, (absl::integer_sequence<int, 1>::size()));
00056 EXPECT_EQ(2, (absl::integer_sequence<int, 1, 2>::size()));
00057 EXPECT_EQ(3, (absl::integer_sequence<int, 0, 1, 2>::size()));
00058 EXPECT_EQ(3, (absl::integer_sequence<int, -123, 123, 456>::size()));
00059 constexpr size_t sz = absl::integer_sequence<int, 0, 1>::size();
00060 EXPECT_EQ(2, sz);
00061 }
00062
00063 TEST(IntegerSequenceTest, MakeIndexSequence) {
00064 StaticAssertTypeEq<absl::index_sequence<>, absl::make_index_sequence<0>>();
00065 StaticAssertTypeEq<absl::index_sequence<0>, absl::make_index_sequence<1>>();
00066 StaticAssertTypeEq<absl::index_sequence<0, 1>,
00067 absl::make_index_sequence<2>>();
00068 StaticAssertTypeEq<absl::index_sequence<0, 1, 2>,
00069 absl::make_index_sequence<3>>();
00070 }
00071
00072 TEST(IntegerSequenceTest, MakeIntegerSequence) {
00073 StaticAssertTypeEq<absl::integer_sequence<int>,
00074 absl::make_integer_sequence<int, 0>>();
00075 StaticAssertTypeEq<absl::integer_sequence<int, 0>,
00076 absl::make_integer_sequence<int, 1>>();
00077 StaticAssertTypeEq<absl::integer_sequence<int, 0, 1>,
00078 absl::make_integer_sequence<int, 2>>();
00079 StaticAssertTypeEq<absl::integer_sequence<int, 0, 1, 2>,
00080 absl::make_integer_sequence<int, 3>>();
00081 }
00082
00083 template <typename... Ts>
00084 class Counter {};
00085
00086 template <size_t... Is>
00087 void CountAll(absl::index_sequence<Is...>) {
00088
00089
00090 ABSL_ATTRIBUTE_UNUSED Counter<absl::make_index_sequence<Is>...> seq;
00091 }
00092
00093
00094
00095
00096 TEST(IntegerSequenceTest, MakeIndexSequencePerformance) {
00097
00098
00099
00100 ABSL_ATTRIBUTE_UNUSED absl::make_index_sequence<(1 << 16) - 1> seq;
00101
00102 CountAll(absl::make_index_sequence<(1 << 8) - 1>());
00103 }
00104
00105 template <typename F, typename Tup, size_t... Is>
00106 auto ApplyFromTupleImpl(F f, const Tup& tup, absl::index_sequence<Is...>)
00107 -> decltype(f(std::get<Is>(tup)...)) {
00108 return f(std::get<Is>(tup)...);
00109 }
00110
00111 template <typename Tup>
00112 using TupIdxSeq = absl::make_index_sequence<std::tuple_size<Tup>::value>;
00113
00114 template <typename F, typename Tup>
00115 auto ApplyFromTuple(F f, const Tup& tup)
00116 -> decltype(ApplyFromTupleImpl(f, tup, TupIdxSeq<Tup>{})) {
00117 return ApplyFromTupleImpl(f, tup, TupIdxSeq<Tup>{});
00118 }
00119
00120 template <typename T>
00121 std::string Fmt(const T& x) {
00122 std::ostringstream os;
00123 os << x;
00124 return os.str();
00125 }
00126
00127 struct PoorStrCat {
00128 template <typename... Args>
00129 std::string operator()(const Args&... args) const {
00130 std::string r;
00131 for (const auto& e : {Fmt(args)...}) r += e;
00132 return r;
00133 }
00134 };
00135
00136 template <typename Tup, size_t... Is>
00137 std::vector<std::string> TupStringVecImpl(const Tup& tup,
00138 absl::index_sequence<Is...>) {
00139 return {Fmt(std::get<Is>(tup))...};
00140 }
00141
00142 template <typename... Ts>
00143 std::vector<std::string> TupStringVec(const std::tuple<Ts...>& tup) {
00144 return TupStringVecImpl(tup, absl::index_sequence_for<Ts...>());
00145 }
00146
00147 TEST(MakeIndexSequenceTest, ApplyFromTupleExample) {
00148 PoorStrCat f{};
00149 EXPECT_EQ("12abc3.14", f(12, "abc", 3.14));
00150 EXPECT_EQ("12abc3.14", ApplyFromTuple(f, std::make_tuple(12, "abc", 3.14)));
00151 }
00152
00153 TEST(IndexSequenceForTest, Basic) {
00154 StaticAssertTypeEq<absl::index_sequence<>, absl::index_sequence_for<>>();
00155 StaticAssertTypeEq<absl::index_sequence<0>, absl::index_sequence_for<int>>();
00156 StaticAssertTypeEq<absl::index_sequence<0, 1, 2, 3>,
00157 absl::index_sequence_for<int, void, char, int>>();
00158 }
00159
00160 TEST(IndexSequenceForTest, Example) {
00161 EXPECT_THAT(TupStringVec(std::make_tuple(12, "abc", 3.14)),
00162 ElementsAre("12", "abc", "3.14"));
00163 }
00164
00165 int Function(int a, int b) { return a - b; }
00166
00167 int Sink(std::unique_ptr<int> p) { return *p; }
00168
00169 std::unique_ptr<int> Factory(int n) { return absl::make_unique<int>(n); }
00170
00171 void NoOp() {}
00172
00173 struct ConstFunctor {
00174 int operator()(int a, int b) const { return a - b; }
00175 };
00176
00177 struct MutableFunctor {
00178 int operator()(int a, int b) { return a - b; }
00179 };
00180
00181 struct EphemeralFunctor {
00182 EphemeralFunctor() {}
00183 EphemeralFunctor(const EphemeralFunctor&) {}
00184 EphemeralFunctor(EphemeralFunctor&&) {}
00185 int operator()(int a, int b) && { return a - b; }
00186 };
00187
00188 struct OverloadedFunctor {
00189 OverloadedFunctor() {}
00190 OverloadedFunctor(const OverloadedFunctor&) {}
00191 OverloadedFunctor(OverloadedFunctor&&) {}
00192 template <typename... Args>
00193 std::string operator()(const Args&... args) & {
00194 return absl::StrCat("&", args...);
00195 }
00196 template <typename... Args>
00197 std::string operator()(const Args&... args) const& {
00198 return absl::StrCat("const&", args...);
00199 }
00200 template <typename... Args>
00201 std::string operator()(const Args&... args) && {
00202 return absl::StrCat("&&", args...);
00203 }
00204 };
00205
00206 struct Class {
00207 int Method(int a, int b) { return a - b; }
00208 int ConstMethod(int a, int b) const { return a - b; }
00209
00210 int member;
00211 };
00212
00213 struct FlipFlop {
00214 int ConstMethod() const { return member; }
00215 FlipFlop operator*() const { return {-member}; }
00216
00217 int member;
00218 };
00219
00220 TEST(ApplyTest, Function) {
00221 EXPECT_EQ(1, absl::apply(Function, std::make_tuple(3, 2)));
00222 EXPECT_EQ(1, absl::apply(&Function, std::make_tuple(3, 2)));
00223 }
00224
00225 TEST(ApplyTest, NonCopyableArgument) {
00226 EXPECT_EQ(42, absl::apply(Sink, std::make_tuple(absl::make_unique<int>(42))));
00227 }
00228
00229 TEST(ApplyTest, NonCopyableResult) {
00230 EXPECT_THAT(absl::apply(Factory, std::make_tuple(42)),
00231 ::testing::Pointee(42));
00232 }
00233
00234 TEST(ApplyTest, VoidResult) { absl::apply(NoOp, std::tuple<>()); }
00235
00236 TEST(ApplyTest, ConstFunctor) {
00237 EXPECT_EQ(1, absl::apply(ConstFunctor(), std::make_tuple(3, 2)));
00238 }
00239
00240 TEST(ApplyTest, MutableFunctor) {
00241 MutableFunctor f;
00242 EXPECT_EQ(1, absl::apply(f, std::make_tuple(3, 2)));
00243 EXPECT_EQ(1, absl::apply(MutableFunctor(), std::make_tuple(3, 2)));
00244 }
00245 TEST(ApplyTest, EphemeralFunctor) {
00246 EphemeralFunctor f;
00247 EXPECT_EQ(1, absl::apply(std::move(f), std::make_tuple(3, 2)));
00248 EXPECT_EQ(1, absl::apply(EphemeralFunctor(), std::make_tuple(3, 2)));
00249 }
00250 TEST(ApplyTest, OverloadedFunctor) {
00251 OverloadedFunctor f;
00252 const OverloadedFunctor& cf = f;
00253
00254 EXPECT_EQ("&", absl::apply(f, std::tuple<>{}));
00255 EXPECT_EQ("& 42", absl::apply(f, std::make_tuple(" 42")));
00256
00257 EXPECT_EQ("const&", absl::apply(cf, std::tuple<>{}));
00258 EXPECT_EQ("const& 42", absl::apply(cf, std::make_tuple(" 42")));
00259
00260 EXPECT_EQ("&&", absl::apply(std::move(f), std::tuple<>{}));
00261 OverloadedFunctor f2;
00262 EXPECT_EQ("&& 42", absl::apply(std::move(f2), std::make_tuple(" 42")));
00263 }
00264
00265 TEST(ApplyTest, ReferenceWrapper) {
00266 ConstFunctor cf;
00267 MutableFunctor mf;
00268 EXPECT_EQ(1, absl::apply(std::cref(cf), std::make_tuple(3, 2)));
00269 EXPECT_EQ(1, absl::apply(std::ref(cf), std::make_tuple(3, 2)));
00270 EXPECT_EQ(1, absl::apply(std::ref(mf), std::make_tuple(3, 2)));
00271 }
00272
00273 TEST(ApplyTest, MemberFunction) {
00274 std::unique_ptr<Class> p(new Class);
00275 std::unique_ptr<const Class> cp(new Class);
00276 EXPECT_EQ(
00277 1, absl::apply(&Class::Method,
00278 std::tuple<std::unique_ptr<Class>&, int, int>(p, 3, 2)));
00279 EXPECT_EQ(1, absl::apply(&Class::Method,
00280 std::tuple<Class*, int, int>(p.get(), 3, 2)));
00281 EXPECT_EQ(
00282 1, absl::apply(&Class::Method, std::tuple<Class&, int, int>(*p, 3, 2)));
00283
00284 EXPECT_EQ(
00285 1, absl::apply(&Class::ConstMethod,
00286 std::tuple<std::unique_ptr<Class>&, int, int>(p, 3, 2)));
00287 EXPECT_EQ(1, absl::apply(&Class::ConstMethod,
00288 std::tuple<Class*, int, int>(p.get(), 3, 2)));
00289 EXPECT_EQ(1, absl::apply(&Class::ConstMethod,
00290 std::tuple<Class&, int, int>(*p, 3, 2)));
00291
00292 EXPECT_EQ(1, absl::apply(&Class::ConstMethod,
00293 std::tuple<std::unique_ptr<const Class>&, int, int>(
00294 cp, 3, 2)));
00295 EXPECT_EQ(1, absl::apply(&Class::ConstMethod,
00296 std::tuple<const Class*, int, int>(cp.get(), 3, 2)));
00297 EXPECT_EQ(1, absl::apply(&Class::ConstMethod,
00298 std::tuple<const Class&, int, int>(*cp, 3, 2)));
00299
00300 EXPECT_EQ(1, absl::apply(&Class::Method,
00301 std::make_tuple(absl::make_unique<Class>(), 3, 2)));
00302 EXPECT_EQ(1, absl::apply(&Class::ConstMethod,
00303 std::make_tuple(absl::make_unique<Class>(), 3, 2)));
00304 EXPECT_EQ(
00305 1, absl::apply(&Class::ConstMethod,
00306 std::make_tuple(absl::make_unique<const Class>(), 3, 2)));
00307 }
00308
00309 TEST(ApplyTest, DataMember) {
00310 std::unique_ptr<Class> p(new Class{42});
00311 std::unique_ptr<const Class> cp(new Class{42});
00312 EXPECT_EQ(
00313 42, absl::apply(&Class::member, std::tuple<std::unique_ptr<Class>&>(p)));
00314 EXPECT_EQ(42, absl::apply(&Class::member, std::tuple<Class&>(*p)));
00315 EXPECT_EQ(42, absl::apply(&Class::member, std::tuple<Class*>(p.get())));
00316
00317 absl::apply(&Class::member, std::tuple<std::unique_ptr<Class>&>(p)) = 42;
00318 absl::apply(&Class::member, std::tuple<Class*>(p.get())) = 42;
00319 absl::apply(&Class::member, std::tuple<Class&>(*p)) = 42;
00320
00321 EXPECT_EQ(42, absl::apply(&Class::member,
00322 std::tuple<std::unique_ptr<const Class>&>(cp)));
00323 EXPECT_EQ(42, absl::apply(&Class::member, std::tuple<const Class&>(*cp)));
00324 EXPECT_EQ(42,
00325 absl::apply(&Class::member, std::tuple<const Class*>(cp.get())));
00326 }
00327
00328 TEST(ApplyTest, FlipFlop) {
00329 FlipFlop obj = {42};
00330
00331
00332 EXPECT_EQ(42, absl::apply(&FlipFlop::ConstMethod, std::make_tuple(obj)));
00333 EXPECT_EQ(42, absl::apply(&FlipFlop::member, std::make_tuple(obj)));
00334 }
00335
00336 TEST(ExchangeTest, MoveOnly) {
00337 auto a = Factory(1);
00338 EXPECT_EQ(1, *a);
00339 auto b = absl::exchange(a, Factory(2));
00340 EXPECT_EQ(2, *a);
00341 EXPECT_EQ(1, *b);
00342 }
00343
00344 }
00345