--- /dev/null
+/*
+ * Copyright 2016 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <folly/Traits.h>
+#include <array>
+#include <type_traits>
+#include <utility>
+
+namespace folly {
+
+namespace array_detail {
+template <typename>
+struct is_ref_wrapper : std::false_type {};
+template <typename T>
+struct is_ref_wrapper<std::reference_wrapper<T>> : std::true_type {};
+
+template <typename T>
+using not_ref_wrapper =
+ folly::Negation<is_ref_wrapper<typename std::decay<T>::type>>;
+
+template <typename D, typename...>
+struct return_type_helper {
+ using type = D;
+};
+template <typename... TList>
+struct return_type_helper<void, TList...> {
+ static_assert(
+ folly::Conjunction<not_ref_wrapper<TList>...>::value,
+ "TList cannot contain reference_wrappers when D is void");
+ using type = typename std::common_type<TList...>::type;
+};
+
+template <typename D, typename... TList>
+using return_type = std::
+ array<typename return_type_helper<D, TList...>::type, sizeof...(TList)>;
+} // !array_detail
+
+template <typename D = void, typename... TList>
+constexpr array_detail::return_type<D, TList...> make_array(TList&&... t) {
+ using value_type =
+ typename array_detail::return_type_helper<D, TList...>::type;
+ return {static_cast<value_type>(std::forward<TList>(t))...};
+}
+
+} // !folly
ApplyTuple.h \
Arena.h \
Arena-inl.h \
+ Array.h \
Assume.h \
AtomicBitSet.h \
AtomicHashArray.h \
traits_detail::has_true_IsZeroInitializable<T>::value
> {};
+template <typename...>
+struct Conjunction : std::true_type {};
+template <typename T>
+struct Conjunction<T> : T {};
+template <typename T, typename... TList>
+struct Conjunction<T, TList...>
+ : std::conditional<T::value, Conjunction<TList...>, T>::type {};
+
+template <typename...>
+struct Disjunction : std::false_type {};
+template <typename T>
+struct Disjunction<T> : T {};
+template <typename T, typename... TList>
+struct Disjunction<T, TList...>
+ : std::conditional<T::value, T, Disjunction<TList...>>::type {};
+
+template <typename T>
+struct Negation : std::integral_constant<bool, !T::value> {};
+
} // namespace folly
/**
--- /dev/null
+/*
+ * Copyright 2016 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <folly/Array.h>
+#include <gtest/gtest.h>
+#include <string>
+
+using namespace std;
+using folly::make_array;
+
+TEST(make_array, base_case) {
+ auto arr = make_array<int>();
+ static_assert(
+ is_same<typename decltype(arr)::value_type, int>::value,
+ "Wrong array type");
+ EXPECT_EQ(arr.size(), 0);
+}
+
+TEST(make_array, deduce_size_primitive) {
+ auto arr = make_array<int>(1, 2, 3, 4, 5);
+ static_assert(
+ is_same<typename decltype(arr)::value_type, int>::value,
+ "Wrong array type");
+ EXPECT_EQ(arr.size(), 5);
+}
+
+TEST(make_array, deduce_size_class) {
+ auto arr = make_array<string>(string{"foo"}, string{"bar"});
+ static_assert(
+ is_same<typename decltype(arr)::value_type, std::string>::value,
+ "Wrong array type");
+ EXPECT_EQ(arr.size(), 2);
+ EXPECT_EQ(arr[1], "bar");
+}
+
+TEST(make_array, deduce_everything) {
+ auto arr = make_array(string{"foo"}, string{"bar"});
+ static_assert(
+ is_same<typename decltype(arr)::value_type, std::string>::value,
+ "Wrong array type");
+ EXPECT_EQ(arr.size(), 2);
+ EXPECT_EQ(arr[1], "bar");
+}
+
+TEST(make_array, fixed_common_type) {
+ auto arr = make_array<double>(1.0, 2.5f, 3, 4, 5);
+ static_assert(
+ is_same<typename decltype(arr)::value_type, double>::value,
+ "Wrong array type");
+ EXPECT_EQ(arr.size(), 5);
+}
+
+TEST(make_array, deduced_common_type) {
+ auto arr = make_array(1.0, 2.5f, 3, 4, 5);
+ static_assert(
+ is_same<typename decltype(arr)::value_type, double>::value,
+ "Wrong array type");
+ EXPECT_EQ(arr.size(), 5);
+}
spin_lock_test_LDADD = libfollytestmain.la
TESTS += spin_lock_test
+array_test_SOURCES = ArrayTest.cpp
+array_test_LDADD = libfollytestmain.la
+TESTS += array_test
+
if RUN_ARCH_SPECIFIC_TESTS
small_locks_test_SOURCES = SmallLocksTest.cpp
small_locks_test_LDADD = libfollytestmain.la
#include <cstring>
#include <string>
+#include <type_traits>
#include <utility>
#include <folly/ScopeGuard.h>
EXPECT_FALSE(IsZeroInitializable<vector<int>>::value);
}
+TEST(Trait, logicOperators) {
+ static_assert(Conjunction<true_type>::value, "");
+ static_assert(!Conjunction<false_type>::value, "");
+ static_assert(is_same<Conjunction<true_type>::type, true_type>::value, "");
+ static_assert(is_same<Conjunction<false_type>::type, false_type>::value, "");
+ static_assert(Conjunction<true_type, true_type>::value, "");
+ static_assert(!Conjunction<true_type, false_type>::value, "");
+
+ static_assert(Disjunction<true_type>::value, "");
+ static_assert(!Disjunction<false_type>::value, "");
+ static_assert(is_same<Disjunction<true_type>::type, true_type>::value, "");
+ static_assert(is_same<Disjunction<false_type>::type, false_type>::value, "");
+ static_assert(Disjunction<true_type, true_type>::value, "");
+ static_assert(Disjunction<true_type, false_type>::value, "");
+
+ static_assert(!Negation<true_type>::value, "");
+ static_assert(Negation<false_type>::value, "");
+}
+
TEST(Traits, is_negative) {
EXPECT_TRUE(folly::is_negative(-1));
EXPECT_FALSE(folly::is_negative(0));