emplace_by_calling_test.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "common/emplace_by_calling.h"
  5. #include <gtest/gtest.h>
  6. #include <list>
  7. namespace Carbon {
  8. namespace {
  9. struct NoncopyableType {
  10. NoncopyableType() = default;
  11. NoncopyableType(const NoncopyableType&) = delete;
  12. auto operator=(const NoncopyableType&) -> NoncopyableType& = delete;
  13. };
  14. auto Make() -> NoncopyableType { return NoncopyableType(); }
  15. TEST(EmplaceByCalling, Noncopyable) {
  16. std::list<NoncopyableType> list;
  17. // This should compile.
  18. list.emplace_back(EmplaceByCalling(Make));
  19. }
  20. TEST(EmplaceByCalling, NoncopyableInAggregate) {
  21. struct Aggregate {
  22. int a, b, c;
  23. NoncopyableType noncopyable;
  24. };
  25. std::list<Aggregate> list;
  26. // This should compile.
  27. list.emplace_back(EmplaceByCalling(
  28. [] { return Aggregate{.a = 1, .b = 2, .c = 3, .noncopyable = Make()}; }));
  29. }
  30. class CopyCounter {
  31. public:
  32. explicit CopyCounter(int* counter) : counter_(counter) {}
  33. CopyCounter(const CopyCounter& other) : counter_(other.counter_) {
  34. ++*counter_;
  35. }
  36. private:
  37. int* counter_;
  38. };
  39. TEST(EmplaceByCalling, NoCopies) {
  40. std::vector<CopyCounter> vec;
  41. vec.reserve(10);
  42. int copies = 0;
  43. for (int i = 0; i != 10; ++i) {
  44. vec.emplace_back(EmplaceByCalling([&] { return CopyCounter(&copies); }));
  45. }
  46. EXPECT_EQ(0, copies);
  47. }
  48. } // namespace
  49. } // namespace Carbon