+++ /dev/null
-/*
- * Copyright 2017 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>
-
-namespace folly {
-
-FOLLY_CREATE_HAS_MEMBER_FN_TRAITS(container_emplace_back_traits, emplace_back);
-
-template <class Container, typename... Args>
-inline
-typename std::enable_if<
- container_emplace_back_traits<Container, void(Args...)>::value>::type
-container_emplace_back_or_push_back(Container& container, Args&&... args) {
- container.emplace_back(std::forward<Args>(args)...);
-}
-
-template <class Container, typename... Args>
-inline
-typename std::enable_if<
- !container_emplace_back_traits<Container, void(Args...)>::value>::type
-container_emplace_back_or_push_back(Container& container, Args&&... args) {
- using v = typename Container::value_type;
- container.push_back(v(std::forward<Args>(args)...));
-}
-
-} // namespace folly
ClockGettimeWrappers.h \
ConcurrentSkipList.h \
ConcurrentSkipList-inl.h \
- ContainerTraits.h \
Conv.h \
CppAttributes.h \
CpuId.h \
#include <boost/iterator/iterator_adaptor.hpp>
-#include <folly/ContainerTraits.h>
#include <folly/Portability.h>
+#include <folly/Traits.h>
/**
* Code that aids in storing data aligned on block (possibly cache-line)
namespace detail {
+template <typename Void, typename Container, typename... Args>
+struct padded_emplace_back_or_push_back_ {
+ static decltype(auto) go(Container& container, Args&&... args) {
+ using Value = typename Container::value_type;
+ return container.push_back(Value(std::forward<Args>(args)...));
+ }
+};
+
+template <typename Container, typename... Args>
+struct padded_emplace_back_or_push_back_<
+ void_t<decltype(
+ std::declval<Container&>().emplace_back(std::declval<Args>()...))>,
+ Container,
+ Args...> {
+ static decltype(auto) go(Container& container, Args&&... args) {
+ return container.emplace_back(std::forward<Args>(args)...);
+ }
+};
+
+template <typename Container, typename... Args>
+decltype(auto) padded_emplace_back_or_push_back(
+ Container& container,
+ Args&&... args) {
+ using impl = padded_emplace_back_or_push_back_<void, Container, Args...>;
+ return impl::go(container, std::forward<Args>(args)...);
+}
+
// Helper class to transfer the constness from From (a lvalue reference)
// and create a lvalue reference to To.
//
private:
value_type* allocate_back() {
if (lastCount_ == Node::kElementCount) {
- container_emplace_back_or_push_back(c_);
+ detail::padded_emplace_back_or_push_back(c_);
lastCount_ = 0;
}
return &c_.back().data()[lastCount_++];
+++ /dev/null
-/*
- * Copyright 2017 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/ContainerTraits.h>
-
-#include <folly/portability/GTest.h>
-
-using namespace std;
-using namespace folly;
-
-struct Node {
- size_t copies = 0;
- Node() noexcept {}
- Node(const Node& n) noexcept { copies = n.copies; ++copies; }
- Node(Node&& n) noexcept { swap(copies, n.copies); ++copies; }
-};
-
-template <class T>
-class VectorWrapper {
- public:
- using value_type = T;
- vector<T>& underlying;
- explicit VectorWrapper(vector<T>& v) : underlying(v) {}
- void push_back(const T& t) { underlying.push_back(t); }
-};
-
-TEST(ContainerTraits, WithoutEmplaceBack) {
- vector<Node> v;
- VectorWrapper<Node> vw(v);
- container_emplace_back_or_push_back(vw);
- EXPECT_EQ(1, v.at(0).copies);
-}
-
-TEST(ContainerTraits, WithEmplaceBack) {
- vector<Node> v;
- container_emplace_back_or_push_back(v);
- EXPECT_EQ(0, v.at(0).copies);
-}