Commit 0f14503e authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Backport C++17 container access functions: size, empty, data

Summary: [Folly] Backport C++17 container access functions: `size`, `empty`, `data`.

Reviewed By: Orvid

Differential Revision: D6301986

fbshipit-source-id: 65c31df68b7743d5ed4a2cf2419586b862683c48
parent ec525ab7
......@@ -331,6 +331,7 @@ if (BUILD_TESTS)
TEST compression_test SOURCES CompressionTest.cpp
DIRECTORY container/test/
TEST access_test SOURCES AccessTest.cpp
TEST array_test SOURCES ArrayTest.cpp
TEST enumerate_test SOURCES EnumerateTest.cpp
TEST evicting_cache_map_test SOURCES EvictingCacheMapTest.cpp
......
......@@ -56,6 +56,7 @@ nobase_follyinclude_HEADERS = \
concurrency/ConcurrentHashMap.h \
concurrency/CoreCachedSharedPtr.h \
concurrency/detail/ConcurrentHashMap-detail.h \
container/Access.h \
container/Array.h \
container/Iterator.h \
container/Enumerate.h \
......
/*
* 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 <initializer_list>
#include <iterator>
/**
* include or backport:
* * std::size
* * std::empty
* * std::data
*/
#if __cpp_lib_nonmember_container_access >= 201411 || _MSC_VER
namespace folly {
/* using override */ using std::size;
/* using override */ using std::empty;
/* using override */ using std::data;
}
#else
namespace folly {
// mimic: std::size, C++17
template <typename C>
constexpr auto size(C const& c) -> decltype(c.size()) {
return c.size();
}
template <typename T, std::size_t N>
constexpr std::size_t size(T const (&)[N]) noexcept {
return N;
}
// mimic: std::empty, C++17
template <typename C>
constexpr auto empty(C const& c) -> decltype(c.empty()) {
return c.empty();
}
template <typename T, std::size_t N>
constexpr bool empty(T const (&)[N]) noexcept {
// while zero-length arrays are not allowed in the language, some compilers
// may permit them in some cases
return N == 0;
}
template <typename E>
constexpr bool empty(std::initializer_list<E> il) noexcept {
return il.size() == 0;
}
// mimic: std::data, C++17
template <typename C>
constexpr auto data(C& c) -> decltype(c.data()) {
return c.data();
}
template <typename C>
constexpr auto data(C const& c) -> decltype(c.data()) {
return c.data();
}
template <typename T, std::size_t N>
constexpr T* data(T (&a)[N]) noexcept {
return a;
}
template <typename E>
constexpr E const* data(std::initializer_list<E> il) noexcept {
return il.begin();
}
}
#endif
/*
* 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/container/Access.h>
#include <array>
#include <initializer_list>
#include <vector>
#include <folly/portability/GTest.h>
class AccessTest : public testing::Test {};
TEST_F(AccessTest, size_vector) {
EXPECT_EQ(3, folly::size(std::vector<int>{1, 2, 3}));
}
TEST_F(AccessTest, size_array) {
constexpr auto const a = std::array<int, 3>{{1, 2, 3}};
constexpr auto const size = folly::size(a);
EXPECT_EQ(3, size);
}
TEST_F(AccessTest, size_carray) {
constexpr int const a[3] = {1, 2, 3};
constexpr auto const size = folly::size(a);
EXPECT_EQ(3, size);
}
TEST_F(AccessTest, size_initializer_list) {
EXPECT_EQ(3, folly::size({1, 2, 3}));
EXPECT_EQ(3, folly::size(std::initializer_list<int>{1, 2, 3}));
}
TEST_F(AccessTest, empty_vector) {
EXPECT_FALSE(folly::empty(std::vector<int>{1, 2, 3}));
EXPECT_TRUE(folly::empty(std::vector<int>{}));
}
TEST_F(AccessTest, empty_array) {
{
constexpr auto const a = std::array<int, 3>{{1, 2, 3}};
constexpr auto const empty = folly::empty(a);
EXPECT_FALSE(empty);
}
{
constexpr auto const a = std::array<int, 0>{{}};
constexpr auto const empty = folly::empty(a);
EXPECT_TRUE(empty);
}
}
TEST_F(AccessTest, empty_carray) {
constexpr int const a[3] = {1, 2, 3};
constexpr auto const empty = folly::empty(a);
EXPECT_FALSE(empty);
// zero-length arrays are not allowed in the language
}
TEST_F(AccessTest, empty_initializer_list) {
EXPECT_FALSE(folly::empty({1, 2, 3}));
EXPECT_FALSE(folly::empty(std::initializer_list<int>{1, 2, 3}));
EXPECT_TRUE(folly::empty(std::initializer_list<int>{}));
}
TEST_F(AccessTest, data_vector) {
EXPECT_EQ(1, *folly::data(std::vector<int>{1, 2, 3}));
auto v = std::vector<int>{1, 2, 3};
*folly::data(v) = 4;
EXPECT_EQ(4, v[0]);
}
TEST_F(AccessTest, data_array) {
constexpr auto const a = std::array<int, 3>{{1, 2, 3}};
auto const data = folly::data(a); // not constexpr until C++17
EXPECT_EQ(1, *data);
}
TEST_F(AccessTest, data_carray) {
constexpr int const a[3] = {1, 2, 3};
auto const data = folly::data(a); // not constexpr until C++17
EXPECT_EQ(1, *data);
}
TEST_F(AccessTest, data_initializer_list) {
EXPECT_EQ(1, *folly::data({1, 2, 3}));
EXPECT_EQ(1, *folly::data(std::initializer_list<int>{1, 2, 3}));
}
......@@ -81,6 +81,9 @@ endif
sorted_vector_types_test_SOURCES = sorted_vector_test.cpp
sorted_vector_types_test_LDADD = libfollytestmain.la
container_access_test_SOURCES = ../container/test/AccessTets.cpp
container_access_test_LDADD = libfollytestmain.la
TESTS += container_access_test
foreach_test_SOURCES = ../container/test/ForeachTest.cpp
foreach_test_LDADD = libfollytestmain.la
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment