2 * Copyright 2014 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "folly/ApplyTuple.h"
20 #include <gtest/gtest.h>
26 void func(int a, int b, double c) {
33 void func(int a, int b, double c) {
37 double retVal(int a, double b) {
42 Wat(Wat const&) = delete;
48 int func(int) { return 0; }
49 bool func(bool) { return true; }
53 int operator()() const {
60 CopyCount(CopyCount const&) {
61 std::cout << "copy count copy ctor\n";
65 void anotherFunc(CopyCount const&) {}
67 std::function<void (int, int, double)> makeFunc() {
72 GuardObjBase(GuardObjBase&&) {}
74 GuardObjBase(GuardObjBase const&) = delete;
75 GuardObjBase& operator=(GuardObjBase const&) = delete;
77 typedef GuardObjBase const& Guard;
79 template<class F, class Tuple>
80 struct GuardObj : GuardObjBase {
81 explicit GuardObj(F&& f, Tuple&& args)
83 , args_(std::move(args))
85 GuardObj(GuardObj&& g)
86 : GuardObjBase(std::move(g))
88 , args_(std::move(g.args_))
92 folly::applyTuple(f_, args_);
95 GuardObj(const GuardObj&) = delete;
96 GuardObj& operator=(const GuardObj&) = delete;
103 template<class F, class ...Args>
104 GuardObj<typename std::decay<F>::type,std::tuple<Args...>>
105 guard(F&& f, Args&&... args) {
106 return GuardObj<typename std::decay<F>::type,std::tuple<Args...>>(
108 std::tuple<Args...>(std::forward<Args>(args)...)
115 Mover(const Mover&) = delete;
116 Mover& operator=(const Mover&) = delete;
119 void move_only_func(Mover&&) {}
123 TEST(ApplyTuple, Test) {
124 auto argsTuple = std::make_tuple(1, 2, 3.0);
126 folly::applyTuple(func2, argsTuple);
127 folly::applyTuple(func, argsTuple);
128 folly::applyTuple(func, std::make_tuple(1, 2, 3.0));
129 folly::applyTuple(makeFunc(), std::make_tuple(1, 2, 3.0));
130 folly::applyTuple(makeFunc(), argsTuple);
132 std::unique_ptr<Wat> wat(new Wat);
133 folly::applyTuple(&Wat::func, std::make_tuple(wat.get(), 1, 2, 3.0));
134 auto argsTuple2 = std::make_tuple(wat.get(), 1, 2, 3.0);
135 folly::applyTuple(&Wat::func, argsTuple2);
138 folly::applyTuple(&Wat::retVal,
139 std::make_tuple(wat.get(), 1, 9.0)));
141 auto test = guard(func, 1, 2, 3.0);
143 auto test2 = guard(anotherFunc, cpy);
144 auto test3 = guard(anotherFunc, std::cref(cpy));
149 static_cast<int (Overloaded::*)(int)>(&Overloaded::func),
150 std::make_tuple(&ovl, 12)));
153 static_cast<bool (Overloaded::*)(bool)>(&Overloaded::func),
154 std::make_tuple(&ovl, false)));
156 int x = folly::applyTuple(std::plus<int>(), std::make_tuple(12, 12));
160 folly::applyTuple(move_only_func,
161 std::forward_as_tuple(std::forward<Mover>(Mover())));