proxygen
HeterogeneousAccessTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-present Facebook, Inc.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
18 
19 #include <set>
20 #include <vector>
21 
22 #include <folly/FBString.h>
23 #include <folly/Portability.h>
24 #include <folly/Range.h>
25 #include <folly/Traits.h>
27 #include <folly/small_vector.h>
28 
29 #if FOLLY_HAS_STRING_VIEW
30 #include <string_view> // @manual
31 #endif
32 
33 using namespace folly;
34 
35 namespace {
36 
37 template <typename T, typename Enable = void>
38 struct IsTransparent : std::false_type {};
39 
40 template <typename T>
41 struct IsTransparent<T, void_t<typename T::is_transparent>> : std::true_type {};
42 
43 template <typename T>
44 void checkTransparent() {
45  static_assert(IsTransparent<HeterogeneousAccessEqualTo<T>>::value, "");
46  static_assert(IsTransparent<HeterogeneousAccessHash<T>>::value, "");
47 }
48 
49 template <typename T>
50 void checkNotTransparent() {
51  static_assert(!IsTransparent<HeterogeneousAccessEqualTo<T>>::value, "");
52  static_assert(!IsTransparent<HeterogeneousAccessHash<T>>::value, "");
53 }
54 
55 struct StringVector {
56  std::vector<std::string> data_;
57 
58  /* implicit */ operator Range<std::string const*>() const {
59  return {&data_[0], data_.size()};
60  }
61 };
62 } // namespace
63 
64 namespace std {
65 template <>
66 struct hash<StringVector> {
67  std::size_t operator()(StringVector const& value) const {
68  return folly::hash::hash_range(value.data_.begin(), value.data_.end());
69  }
70 };
71 } // namespace std
72 
73 TEST(HeterogeneousAccess, transparentIsSelected) {
74  checkTransparent<std::string>();
75  checkTransparent<std::wstring>();
76  checkTransparent<std::u16string>();
77  checkTransparent<std::u32string>();
78 
79 #if FOLLY_HAS_STRING_VIEW
80  checkTransparent<std::string_view>();
81  checkTransparent<std::wstring_view>();
82  checkTransparent<std::u16string_view>();
83  checkTransparent<std::u32string_view>();
84 #endif
85 
86  checkTransparent<fbstring>();
87 
88  checkTransparent<StringPiece>();
89  checkTransparent<MutableStringPiece>();
90 
91  checkTransparent<Range<char const*>>();
92  checkTransparent<Range<wchar_t const*>>();
93  checkTransparent<Range<char16_t const*>>();
94  checkTransparent<Range<char32_t const*>>();
95  checkTransparent<Range<int const*>>();
96 
97  checkTransparent<Range<char*>>();
98  checkTransparent<Range<wchar_t*>>();
99  checkTransparent<Range<char16_t*>>();
100  checkTransparent<Range<char32_t*>>();
101  checkTransparent<Range<int*>>();
102 
103  checkTransparent<std::vector<char>>();
104  checkTransparent<std::vector<wchar_t>>();
105  checkTransparent<std::vector<char16_t>>();
106  checkTransparent<std::vector<char32_t>>();
107  checkTransparent<std::vector<int>>();
108 
109  checkTransparent<std::array<char const, 2>>();
110  checkTransparent<std::array<wchar_t const, 2>>();
111  checkTransparent<std::array<char16_t const, 2>>();
112  checkTransparent<std::array<char32_t const, 2>>();
113  checkTransparent<std::array<int const, 2>>();
114 
115  checkTransparent<std::array<char, 2>>();
116  checkTransparent<std::array<wchar_t, 2>>();
117  checkTransparent<std::array<char16_t, 2>>();
118  checkTransparent<std::array<char32_t, 2>>();
119  checkTransparent<std::array<int, 2>>();
120 }
121 
122 TEST(HeterogeneousAccess, transparentIsNotSelected) {
123  checkNotTransparent<char>();
124  checkNotTransparent<int>();
125  checkNotTransparent<float>();
126  checkNotTransparent<std::pair<StringPiece, StringPiece>>();
127  checkNotTransparent<StringVector>(); // no folly::hasher for Range
128 }
129 
130 template <typename L, typename R, typename S>
131 void runTestMatches2(S src) {
132  S smaller{src};
133  smaller.resize(smaller.size() - 1);
134 
135  using RangeType = Range<typename S::value_type*>;
136 
137  L lhs1{RangeType{&src[0], src.size()}};
138  L lhs2{RangeType{&smaller[0], smaller.size()}};
139  R rhs1{RangeType{&src[0], src.size()}};
140  R rhs2{RangeType{&smaller[0], smaller.size()}};
141 
144 
145  EXPECT_TRUE(equalTo(lhs1, rhs1));
146  EXPECT_FALSE(equalTo(lhs1, rhs2));
147  EXPECT_FALSE(equalTo(lhs2, rhs1));
148  EXPECT_TRUE(equalTo(lhs2, rhs2));
149 
150  EXPECT_EQ(hash(lhs1), hash(rhs1));
151  EXPECT_NE(hash(lhs1), hash(rhs2)); // technically only low probability
152  EXPECT_NE(hash(lhs2), hash(rhs1)); // technically only low probability
153  EXPECT_EQ(hash(lhs2), hash(rhs2));
154 
155  auto v0 = smaller[0];
156  std::array<decltype(v0), 1> a{{v0}};
157  EXPECT_FALSE(equalTo(a, lhs1));
158  EXPECT_FALSE(equalTo(a, rhs1));
159 
160  smaller.resize(1);
161  EXPECT_FALSE(equalTo(a, lhs1));
162  EXPECT_FALSE(equalTo(a, lhs2));
163  EXPECT_TRUE(equalTo(a, smaller));
164 
165  EXPECT_EQ(hash(a), hash(smaller));
166 }
167 
168 template <typename S>
169 void runTestMatches(S const& src) {
171  using MSP = Range<typename S::value_type*>;
172 #if FOLLY_HAS_STRING_VIEW
173  using SV = std::basic_string_view<typename S::value_type>;
174 #else
175  using SV = SP;
176 #endif
177  using V = std::vector<typename S::value_type>;
178 
179  runTestMatches2<S, S>(src);
180  runTestMatches2<S, SP>(src);
181  runTestMatches2<S, MSP>(src);
182  runTestMatches2<S, SV>(src);
183  runTestMatches2<S, V>(src);
184  runTestMatches2<SP, S>(src);
185  runTestMatches2<SP, SP>(src);
186  runTestMatches2<SP, MSP>(src);
187  runTestMatches2<SP, SV>(src);
188  runTestMatches2<SP, V>(src);
189  runTestMatches2<MSP, S>(src);
190  runTestMatches2<MSP, SP>(src);
191  runTestMatches2<MSP, MSP>(src);
192  runTestMatches2<MSP, SV>(src);
193  runTestMatches2<MSP, V>(src);
194  runTestMatches2<SV, S>(src);
195  runTestMatches2<SV, SP>(src);
196  runTestMatches2<SV, MSP>(src);
197  runTestMatches2<SV, SV>(src);
198  runTestMatches2<SV, V>(src);
199  runTestMatches2<V, S>(src);
200  runTestMatches2<V, SP>(src);
201  runTestMatches2<V, MSP>(src);
202  runTestMatches2<V, SV>(src);
203  runTestMatches2<V, V>(src);
204 }
205 
207  return sv;
208 }
209 
210 TEST(HeterogeneousAccess, transparentMatches) {
211  runTestMatches<std::string>("abcd");
212  runTestMatches<std::string>(u8"abcd");
213  runTestMatches<std::wstring>(L"abcd");
214  runTestMatches<std::u16string>(u"abcd");
215  runTestMatches<std::u32string>(U"abcd");
216  runTestMatches<fbstring>("abcd");
217  runTestMatches<std::vector<int>>({1, 2, 3, 4});
218 
219  static_assert(
220  std::is_convertible<small_vector<int, 2>, Range<int const*>>::value, "");
221  runTestMatches<small_vector<int, 2>>({1, 2, 3, 4});
222 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
STL namespace.
folly::std T
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
bool_constant< true > true_type
Definition: gtest-port.h:2210
vector< std::string > StringVector
uint64_t hash_range(Iter begin, Iter end, uint64_t hash=0, Hash hasher=Hash())
Definition: Hash.h:604
auto const foo
Definition: LazyTest.cpp:49
void runTestMatches(S const &src)
type_t< void, Ts... > void_t
Definition: Traits.h:302
char a
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
bool_constant< false > false_type
Definition: gtest-port.h:2209
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
void runTestMatches2(S src)
TEST(SequencedExecutor, CPUThreadPoolExecutor)
std::size_t operator()(StringVector const &value) const
StringPiece data_