meta_container.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. #include <array>
  2. #include <map>
  3. #include <set>
  4. #include <utility>
  5. #include <vector>
  6. #include <gtest/gtest.h>
  7. #include <entt/core/hashed_string.hpp>
  8. #include <entt/meta/container.hpp>
  9. #include <entt/meta/factory.hpp>
  10. #include <entt/meta/meta.hpp>
  11. #include <entt/meta/resolve.hpp>
  12. struct invalid_type {};
  13. struct MetaContainer: ::testing::Test {
  14. void SetUp() override {
  15. using namespace entt::literals;
  16. entt::meta<double>()
  17. .type("double"_hs);
  18. entt::meta<int>()
  19. .type("int"_hs);
  20. }
  21. void TearDown() override {
  22. entt::meta_reset();
  23. }
  24. };
  25. using MetaContainerDeathTest = MetaContainer;
  26. TEST_F(MetaContainer, InvalidContainer) {
  27. ASSERT_FALSE(entt::meta_any{42}.as_sequence_container());
  28. ASSERT_FALSE(entt::meta_any{42}.as_associative_container());
  29. ASSERT_FALSE((entt::meta_any{std::map<int, char>{}}.as_sequence_container()));
  30. ASSERT_FALSE(entt::meta_any{std::vector<int>{}}.as_associative_container());
  31. }
  32. TEST_F(MetaContainer, EmptySequenceContainer) {
  33. entt::meta_sequence_container container{};
  34. ASSERT_FALSE(container);
  35. entt::meta_any any{std::vector<int>{}};
  36. container = any.as_sequence_container();
  37. ASSERT_TRUE(container);
  38. }
  39. TEST_F(MetaContainer, EmptyAssociativeContainer) {
  40. entt::meta_associative_container container{};
  41. ASSERT_FALSE(container);
  42. entt::meta_any any{std::map<int, char>{}};
  43. container = any.as_associative_container();
  44. ASSERT_TRUE(container);
  45. }
  46. TEST_F(MetaContainer, SequenceContainerIterator) {
  47. std::vector<int> vec{2, 3, 4};
  48. auto any = entt::forward_as_meta(vec);
  49. entt::meta_sequence_container::iterator first{};
  50. auto view = any.as_sequence_container();
  51. ASSERT_FALSE(first);
  52. first = view.begin();
  53. const auto last = view.end();
  54. ASSERT_TRUE(first);
  55. ASSERT_TRUE(last);
  56. ASSERT_FALSE(first == last);
  57. ASSERT_TRUE(first != last);
  58. ASSERT_EQ((first++)->cast<int>(), 2);
  59. ASSERT_EQ((++first)->cast<int>(), 4);
  60. ASSERT_NE(first++, last);
  61. ASSERT_TRUE(first == last);
  62. ASSERT_FALSE(first != last);
  63. ASSERT_EQ(first--, last);
  64. ASSERT_EQ((first--)->cast<int>(), 4);
  65. ASSERT_EQ((--first)->cast<int>(), 2);
  66. }
  67. TEST_F(MetaContainer, AssociativeContainerIterator) {
  68. std::map<int, char> map{{2, 'c'}, {3, 'd'}, {4, 'e'}};
  69. auto any = entt::forward_as_meta(map);
  70. entt::meta_associative_container::iterator first{};
  71. auto view = any.as_associative_container();
  72. ASSERT_FALSE(first);
  73. first = view.begin();
  74. const auto last = view.end();
  75. ASSERT_TRUE(first);
  76. ASSERT_TRUE(last);
  77. ASSERT_FALSE(first == last);
  78. ASSERT_TRUE(first != last);
  79. ASSERT_NE(first, last);
  80. ASSERT_EQ((first++)->first.cast<int>(), 2);
  81. ASSERT_EQ((++first)->second.cast<char>(), 'e');
  82. ASSERT_NE(first++, last);
  83. ASSERT_EQ(first, last);
  84. ASSERT_TRUE(first == last);
  85. ASSERT_FALSE(first != last);
  86. }
  87. TEST_F(MetaContainer, StdVector) {
  88. std::vector<int> vec{};
  89. auto any = entt::forward_as_meta(vec);
  90. auto view = any.as_sequence_container();
  91. ASSERT_TRUE(view);
  92. ASSERT_EQ(view.value_type(), entt::resolve<int>());
  93. ASSERT_EQ(view.size(), 0u);
  94. ASSERT_EQ(view.begin(), view.end());
  95. ASSERT_TRUE(view.resize(3u));
  96. ASSERT_EQ(view.size(), 3u);
  97. ASSERT_NE(view.begin(), view.end());
  98. view[0].cast<int &>() = 2;
  99. view[1].cast<int &>() = 3;
  100. view[2].cast<int &>() = 4;
  101. ASSERT_EQ(view[1u].cast<int>(), 3);
  102. auto it = view.begin();
  103. auto ret = view.insert(it, 0);
  104. ASSERT_TRUE(ret);
  105. ASSERT_FALSE(view.insert(ret, invalid_type{}));
  106. ASSERT_TRUE(view.insert(++ret, 1.));
  107. ASSERT_EQ(view.size(), 5u);
  108. ASSERT_EQ(view.begin()->cast<int>(), 0);
  109. ASSERT_EQ((++view.begin())->cast<int>(), 1);
  110. ret = view.insert(view.end(), 42);
  111. ASSERT_TRUE(ret);
  112. ASSERT_EQ(*ret, 42);
  113. it = view.begin();
  114. ret = view.erase(it);
  115. ASSERT_TRUE(ret);
  116. ASSERT_EQ(view.size(), 5u);
  117. ASSERT_EQ(ret->cast<int>(), 1);
  118. ASSERT_TRUE(view.clear());
  119. ASSERT_EQ(view.size(), 0u);
  120. }
  121. TEST_F(MetaContainer, StdArray) {
  122. std::array<int, 3> arr{};
  123. auto any = entt::forward_as_meta(arr);
  124. auto view = any.as_sequence_container();
  125. ASSERT_TRUE(view);
  126. ASSERT_EQ(view.value_type(), entt::resolve<int>());
  127. ASSERT_EQ(view.size(), 3u);
  128. ASSERT_NE(view.begin(), view.end());
  129. ASSERT_FALSE(view.resize(5u));
  130. ASSERT_EQ(view.size(), 3u);
  131. view[0].cast<int &>() = 2;
  132. view[1].cast<int &>() = 3;
  133. view[2].cast<int &>() = 4;
  134. ASSERT_EQ(view[1u].cast<int>(), 3);
  135. auto it = view.begin();
  136. auto ret = view.insert(it, 0);
  137. ASSERT_FALSE(ret);
  138. ASSERT_FALSE(view.insert(it, 'c'));
  139. ASSERT_FALSE(view.insert(++it, 1.));
  140. ASSERT_EQ(view.size(), 3u);
  141. ASSERT_EQ(view.begin()->cast<int>(), 2);
  142. ASSERT_EQ((++view.begin())->cast<int>(), 3);
  143. it = view.begin();
  144. ret = view.erase(it);
  145. ASSERT_FALSE(ret);
  146. ASSERT_EQ(view.size(), 3u);
  147. ASSERT_EQ(it->cast<int>(), 2);
  148. ASSERT_FALSE(view.clear());
  149. ASSERT_EQ(view.size(), 3u);
  150. }
  151. TEST_F(MetaContainer, StdMap) {
  152. std::map<int, char> map{{2, 'c'}, {3, 'd'}, {4, 'e'}};
  153. auto any = entt::forward_as_meta(map);
  154. auto view = any.as_associative_container();
  155. ASSERT_TRUE(view);
  156. ASSERT_FALSE(view.key_only());
  157. ASSERT_EQ(view.key_type(), entt::resolve<int>());
  158. ASSERT_EQ(view.mapped_type(), entt::resolve<char>());
  159. ASSERT_EQ(view.value_type(), (entt::resolve<std::pair<const int, char>>()));
  160. ASSERT_EQ(view.size(), 3u);
  161. ASSERT_NE(view.begin(), view.end());
  162. ASSERT_EQ(view.find(3)->second.cast<char>(), 'd');
  163. ASSERT_FALSE(view.insert(invalid_type{}, 'a'));
  164. ASSERT_FALSE(view.insert(1, invalid_type{}));
  165. ASSERT_TRUE(view.insert(0, 'a'));
  166. ASSERT_TRUE(view.insert(1., static_cast<int>('b')));
  167. ASSERT_EQ(view.size(), 5u);
  168. ASSERT_EQ(view.find(0)->second.cast<char>(), 'a');
  169. ASSERT_EQ(view.find(1.)->second.cast<char>(), 'b');
  170. ASSERT_FALSE(view.erase(invalid_type{}));
  171. ASSERT_FALSE(view.find(invalid_type{}));
  172. ASSERT_EQ(view.size(), 5u);
  173. ASSERT_TRUE(view.erase(0));
  174. ASSERT_EQ(view.size(), 4u);
  175. ASSERT_EQ(view.find(0), view.end());
  176. view.find(1.)->second.cast<char &>() = 'f';
  177. ASSERT_EQ(view.find(1.f)->second.cast<char>(), 'f');
  178. ASSERT_TRUE(view.erase(1.));
  179. ASSERT_TRUE(view.clear());
  180. ASSERT_EQ(view.size(), 0u);
  181. }
  182. TEST_F(MetaContainer, StdSet) {
  183. std::set<int> set{2, 3, 4};
  184. auto any = entt::forward_as_meta(set);
  185. auto view = any.as_associative_container();
  186. ASSERT_TRUE(view);
  187. ASSERT_TRUE(view.key_only());
  188. ASSERT_EQ(view.key_type(), entt::resolve<int>());
  189. ASSERT_EQ(view.mapped_type(), entt::meta_type{});
  190. ASSERT_EQ(view.value_type(), entt::resolve<int>());
  191. ASSERT_EQ(view.size(), 3u);
  192. ASSERT_NE(view.begin(), view.end());
  193. ASSERT_EQ(view.find(3)->first.cast<int>(), 3);
  194. ASSERT_FALSE(view.insert(invalid_type{}));
  195. ASSERT_TRUE(view.insert(.0));
  196. ASSERT_TRUE(view.insert(1));
  197. ASSERT_EQ(view.size(), 5u);
  198. ASSERT_EQ(view.find(0)->first.cast<int>(), 0);
  199. ASSERT_EQ(view.find(1.)->first.cast<int>(), 1);
  200. ASSERT_FALSE(view.erase(invalid_type{}));
  201. ASSERT_FALSE(view.find(invalid_type{}));
  202. ASSERT_EQ(view.size(), 5u);
  203. ASSERT_TRUE(view.erase(0));
  204. ASSERT_EQ(view.size(), 4u);
  205. ASSERT_EQ(view.find(0), view.end());
  206. ASSERT_EQ(view.find(1.f)->first.try_cast<int>(), nullptr);
  207. ASSERT_NE(view.find(1.)->first.try_cast<const int>(), nullptr);
  208. ASSERT_EQ(view.find(true)->first.cast<const int &>(), 1);
  209. ASSERT_TRUE(view.erase(1.));
  210. ASSERT_TRUE(view.clear());
  211. ASSERT_EQ(view.size(), 0u);
  212. }
  213. TEST_F(MetaContainer, DenseMap) {
  214. entt::dense_map<int, char> map{};
  215. auto any = entt::forward_as_meta(map);
  216. auto view = any.as_associative_container();
  217. map.emplace(2, 'c');
  218. map.emplace(3, 'd');
  219. map.emplace(4, '3');
  220. ASSERT_TRUE(view);
  221. ASSERT_FALSE(view.key_only());
  222. ASSERT_EQ(view.key_type(), entt::resolve<int>());
  223. ASSERT_EQ(view.mapped_type(), entt::resolve<char>());
  224. ASSERT_EQ(view.value_type(), (entt::resolve<std::pair<const int, char>>()));
  225. ASSERT_EQ(view.size(), 3u);
  226. ASSERT_NE(view.begin(), view.end());
  227. ASSERT_EQ(view.find(3)->second.cast<char>(), 'd');
  228. ASSERT_FALSE(view.insert(invalid_type{}, 'a'));
  229. ASSERT_FALSE(view.insert(1, invalid_type{}));
  230. ASSERT_TRUE(view.insert(0, 'a'));
  231. ASSERT_TRUE(view.insert(1., static_cast<int>('b')));
  232. ASSERT_EQ(view.size(), 5u);
  233. ASSERT_EQ(view.find(0)->second.cast<char>(), 'a');
  234. ASSERT_EQ(view.find(1.)->second.cast<char>(), 'b');
  235. ASSERT_FALSE(view.erase(invalid_type{}));
  236. ASSERT_FALSE(view.find(invalid_type{}));
  237. ASSERT_EQ(view.size(), 5u);
  238. ASSERT_TRUE(view.erase(0));
  239. ASSERT_EQ(view.size(), 4u);
  240. ASSERT_EQ(view.find(0), view.end());
  241. view.find(1.)->second.cast<char &>() = 'f';
  242. ASSERT_EQ(view.find(1.f)->second.cast<char>(), 'f');
  243. ASSERT_TRUE(view.erase(1.));
  244. ASSERT_TRUE(view.clear());
  245. ASSERT_EQ(view.size(), 0u);
  246. }
  247. TEST_F(MetaContainer, DenseSet) {
  248. entt::dense_set<int> set{};
  249. auto any = entt::forward_as_meta(set);
  250. auto view = any.as_associative_container();
  251. set.emplace(2);
  252. set.emplace(3);
  253. set.emplace(4);
  254. ASSERT_TRUE(view);
  255. ASSERT_TRUE(view.key_only());
  256. ASSERT_EQ(view.key_type(), entt::resolve<int>());
  257. ASSERT_EQ(view.mapped_type(), entt::meta_type{});
  258. ASSERT_EQ(view.value_type(), entt::resolve<int>());
  259. ASSERT_EQ(view.size(), 3u);
  260. ASSERT_NE(view.begin(), view.end());
  261. ASSERT_EQ(view.find(3)->first.cast<int>(), 3);
  262. ASSERT_FALSE(view.insert(invalid_type{}));
  263. ASSERT_TRUE(view.insert(.0));
  264. ASSERT_TRUE(view.insert(1));
  265. ASSERT_EQ(view.size(), 5u);
  266. ASSERT_EQ(view.find(0)->first.cast<int>(), 0);
  267. ASSERT_EQ(view.find(1.)->first.cast<int>(), 1);
  268. ASSERT_FALSE(view.erase(invalid_type{}));
  269. ASSERT_FALSE(view.find(invalid_type{}));
  270. ASSERT_EQ(view.size(), 5u);
  271. ASSERT_TRUE(view.erase(0));
  272. ASSERT_EQ(view.size(), 4u);
  273. ASSERT_EQ(view.find(0), view.end());
  274. ASSERT_EQ(view.find(1.f)->first.try_cast<int>(), nullptr);
  275. ASSERT_NE(view.find(1.)->first.try_cast<const int>(), nullptr);
  276. ASSERT_EQ(view.find(true)->first.cast<const int &>(), 1);
  277. ASSERT_TRUE(view.erase(1.));
  278. ASSERT_TRUE(view.clear());
  279. ASSERT_EQ(view.size(), 0u);
  280. }
  281. TEST_F(MetaContainer, ConstSequenceContainer) {
  282. std::vector<int> vec{};
  283. auto any = entt::forward_as_meta(std::as_const(vec));
  284. auto view = any.as_sequence_container();
  285. ASSERT_TRUE(view);
  286. ASSERT_EQ(view.value_type(), entt::resolve<int>());
  287. ASSERT_EQ(view.size(), 0u);
  288. ASSERT_EQ(view.begin(), view.end());
  289. ASSERT_FALSE(view.resize(3u));
  290. ASSERT_EQ(view.size(), 0u);
  291. ASSERT_EQ(view.begin(), view.end());
  292. vec.push_back(42);
  293. ASSERT_EQ(view.size(), 1u);
  294. ASSERT_NE(view.begin(), view.end());
  295. ASSERT_EQ(view[0].cast<const int &>(), 42);
  296. auto it = view.begin();
  297. auto ret = view.insert(it, 0);
  298. ASSERT_FALSE(ret);
  299. ASSERT_EQ(view.size(), 1u);
  300. ASSERT_EQ(it->cast<int>(), 42);
  301. ASSERT_EQ(++it, view.end());
  302. it = view.begin();
  303. ret = view.erase(it);
  304. ASSERT_FALSE(ret);
  305. ASSERT_EQ(view.size(), 1u);
  306. ASSERT_FALSE(view.clear());
  307. ASSERT_EQ(view.size(), 1u);
  308. }
  309. TEST_F(MetaContainerDeathTest, ConstSequenceContainer) {
  310. std::vector<int> vec{};
  311. auto any = entt::forward_as_meta(std::as_const(vec));
  312. auto view = any.as_sequence_container();
  313. ASSERT_TRUE(view);
  314. ASSERT_DEATH(view[0].cast<int &>() = 2, "");
  315. }
  316. TEST_F(MetaContainer, ConstKeyValueAssociativeContainer) {
  317. std::map<int, char> map{};
  318. auto any = entt::forward_as_meta(std::as_const(map));
  319. auto view = any.as_associative_container();
  320. ASSERT_TRUE(view);
  321. ASSERT_FALSE(view.key_only());
  322. ASSERT_EQ(view.key_type(), entt::resolve<int>());
  323. ASSERT_EQ(view.mapped_type(), entt::resolve<char>());
  324. ASSERT_EQ(view.value_type(), (entt::resolve<std::pair<const int, char>>()));
  325. ASSERT_EQ(view.size(), 0u);
  326. ASSERT_EQ(view.begin(), view.end());
  327. map[2] = 'c';
  328. ASSERT_EQ(view.size(), 1u);
  329. ASSERT_NE(view.begin(), view.end());
  330. ASSERT_EQ(view.find(2)->second.cast<const char &>(), 'c');
  331. ASSERT_FALSE(view.insert(0, 'a'));
  332. ASSERT_EQ(view.size(), 1u);
  333. ASSERT_EQ(view.find(0), view.end());
  334. ASSERT_EQ(view.find(2)->second.cast<char>(), 'c');
  335. ASSERT_FALSE(view.erase(2));
  336. ASSERT_EQ(view.size(), 1u);
  337. ASSERT_NE(view.find(2), view.end());
  338. ASSERT_FALSE(view.clear());
  339. ASSERT_EQ(view.size(), 1u);
  340. }
  341. TEST_F(MetaContainerDeathTest, ConstKeyValueAssociativeContainer) {
  342. std::map<int, char> map{};
  343. auto any = entt::forward_as_meta(std::as_const(map));
  344. auto view = any.as_associative_container();
  345. ASSERT_TRUE(view);
  346. ASSERT_DEATH(view.find(2)->second.cast<char &>() = 'a', "");
  347. }
  348. TEST_F(MetaContainer, ConstKeyOnlyAssociativeContainer) {
  349. std::set<int> set{};
  350. auto any = entt::forward_as_meta(std::as_const(set));
  351. auto view = any.as_associative_container();
  352. ASSERT_TRUE(view);
  353. ASSERT_TRUE(view.key_only());
  354. ASSERT_EQ(view.key_type(), entt::resolve<int>());
  355. ASSERT_EQ(view.mapped_type(), entt::meta_type{});
  356. ASSERT_EQ(view.value_type(), (entt::resolve<int>()));
  357. ASSERT_EQ(view.size(), 0u);
  358. ASSERT_EQ(view.begin(), view.end());
  359. set.insert(2);
  360. ASSERT_EQ(view.size(), 1u);
  361. ASSERT_NE(view.begin(), view.end());
  362. ASSERT_EQ(view.find(2)->first.try_cast<int>(), nullptr);
  363. ASSERT_NE(view.find(2)->first.try_cast<const int>(), nullptr);
  364. ASSERT_EQ(view.find(2)->first.cast<int>(), 2);
  365. ASSERT_EQ(view.find(2)->first.cast<const int &>(), 2);
  366. ASSERT_FALSE(view.insert(0));
  367. ASSERT_EQ(view.size(), 1u);
  368. ASSERT_EQ(view.find(0), view.end());
  369. ASSERT_EQ(view.find(2)->first.cast<int>(), 2);
  370. ASSERT_FALSE(view.erase(2));
  371. ASSERT_EQ(view.size(), 1u);
  372. ASSERT_NE(view.find(2), view.end());
  373. ASSERT_FALSE(view.clear());
  374. ASSERT_EQ(view.size(), 1u);
  375. }
  376. TEST_F(MetaContainer, SequenceContainerConstMetaAny) {
  377. auto test = [](const entt::meta_any any) {
  378. auto view = any.as_sequence_container();
  379. ASSERT_TRUE(view);
  380. ASSERT_EQ(view.value_type(), entt::resolve<int>());
  381. ASSERT_EQ(view[0].cast<const int &>(), 42);
  382. };
  383. std::vector<int> vec{42};
  384. test(vec);
  385. test(entt::forward_as_meta(vec));
  386. test(entt::forward_as_meta(std::as_const(vec)));
  387. }
  388. TEST_F(MetaContainerDeathTest, SequenceContainerConstMetaAny) {
  389. auto test = [](const entt::meta_any any) {
  390. auto view = any.as_sequence_container();
  391. ASSERT_TRUE(view);
  392. ASSERT_DEATH(view[0].cast<int &>() = 2, "");
  393. };
  394. std::vector<int> vec{42};
  395. test(vec);
  396. test(entt::forward_as_meta(vec));
  397. test(entt::forward_as_meta(std::as_const(vec)));
  398. }
  399. TEST_F(MetaContainer, KeyValueAssociativeContainerConstMetaAny) {
  400. auto test = [](const entt::meta_any any) {
  401. auto view = any.as_associative_container();
  402. ASSERT_TRUE(view);
  403. ASSERT_EQ(view.value_type(), (entt::resolve<std::pair<const int, char>>()));
  404. ASSERT_EQ(view.find(2)->second.cast<const char &>(), 'c');
  405. };
  406. std::map<int, char> map{{2, 'c'}};
  407. test(map);
  408. test(entt::forward_as_meta(map));
  409. test(entt::forward_as_meta(std::as_const(map)));
  410. }
  411. TEST_F(MetaContainerDeathTest, KeyValueAssociativeContainerConstMetaAny) {
  412. auto test = [](const entt::meta_any any) {
  413. auto view = any.as_associative_container();
  414. ASSERT_TRUE(view);
  415. ASSERT_DEATH(view.find(2)->second.cast<char &>() = 'a', "");
  416. };
  417. std::map<int, char> map{{2, 'c'}};
  418. test(map);
  419. test(entt::forward_as_meta(map));
  420. test(entt::forward_as_meta(std::as_const(map)));
  421. }
  422. TEST_F(MetaContainer, KeyOnlyAssociativeContainerConstMetaAny) {
  423. auto test = [](const entt::meta_any any) {
  424. auto view = any.as_associative_container();
  425. ASSERT_TRUE(view);
  426. ASSERT_EQ(view.value_type(), (entt::resolve<int>()));
  427. ASSERT_EQ(view.find(2)->first.try_cast<int>(), nullptr);
  428. ASSERT_NE(view.find(2)->first.try_cast<const int>(), nullptr);
  429. ASSERT_EQ(view.find(2)->first.cast<int>(), 2);
  430. ASSERT_EQ(view.find(2)->first.cast<const int &>(), 2);
  431. };
  432. std::set<int> set{2};
  433. test(set);
  434. test(entt::forward_as_meta(set));
  435. test(entt::forward_as_meta(std::as_const(set)));
  436. }
  437. TEST_F(MetaContainer, StdVectorBool) {
  438. using proxy_type = typename std::vector<bool>::reference;
  439. using const_proxy_type = typename std::vector<bool>::const_reference;
  440. std::vector<bool> vec{};
  441. auto any = entt::forward_as_meta(vec);
  442. auto cany = std::as_const(any).as_ref();
  443. auto view = any.as_sequence_container();
  444. auto cview = cany.as_sequence_container();
  445. ASSERT_TRUE(view);
  446. ASSERT_EQ(view.value_type(), entt::resolve<bool>());
  447. ASSERT_EQ(view.size(), 0u);
  448. ASSERT_EQ(view.begin(), view.end());
  449. ASSERT_TRUE(view.resize(3u));
  450. ASSERT_EQ(view.size(), 3u);
  451. ASSERT_NE(view.begin(), view.end());
  452. view[0].cast<proxy_type>() = true;
  453. view[1].cast<proxy_type>() = true;
  454. view[2].cast<proxy_type>() = false;
  455. ASSERT_EQ(cview[1u].cast<const_proxy_type>(), true);
  456. auto it = view.begin();
  457. auto ret = view.insert(it, true);
  458. ASSERT_TRUE(ret);
  459. ASSERT_FALSE(view.insert(ret, invalid_type{}));
  460. ASSERT_TRUE(view.insert(++ret, false));
  461. ASSERT_EQ(view.size(), 5u);
  462. ASSERT_EQ(view.begin()->cast<proxy_type>(), true);
  463. ASSERT_EQ((++cview.begin())->cast<const_proxy_type>(), false);
  464. it = view.begin();
  465. ret = view.erase(it);
  466. ASSERT_TRUE(ret);
  467. ASSERT_EQ(view.size(), 4u);
  468. ASSERT_EQ(ret->cast<proxy_type>(), false);
  469. ASSERT_TRUE(view.clear());
  470. ASSERT_EQ(cview.size(), 0u);
  471. }