fork download
  1. #include <cstddef>
  2. #include <cstdlib>
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <functional>
  7. #include <type_traits>
  8.  
  9. template <typename Type, bool Selector>
  10. struct default_creator_impl;
  11.  
  12. template <typename Type, bool Selector>
  13. struct default_deleter_impl;
  14.  
  15. // for non-POD types
  16. template <typename Type>
  17. struct default_creator_impl<Type, false>
  18. {
  19. Type* operator()()
  20. {
  21. Type* object = static_cast<Type*>(std::malloc(sizeof(Type)));
  22. return new (object) Type;
  23. }
  24. };
  25.  
  26. template <typename Type>
  27. struct default_deleter_impl<Type, false>
  28. {
  29. void operator()(void* object)
  30. {
  31. reinterpret_cast<Type*>(object)->Type::~Type();
  32. free(object);
  33. }
  34. };
  35.  
  36. // for simple types
  37. template <typename Type>
  38. struct default_creator_impl<Type, true>
  39. {
  40. Type* operator()()
  41. {
  42. return static_cast<Type*>(std::malloc(sizeof(Type)));
  43. }
  44. };
  45.  
  46. template <typename Type>
  47. struct default_deleter_impl<Type, true>
  48. {
  49. void operator()(void* object)
  50. {
  51. free(object);
  52. }
  53. };
  54.  
  55. template <typename Type>
  56. using default_creator = default_creator_impl<Type, std::has_trivial_default_constructor<Type>::value>;
  57.  
  58. template <typename Type>
  59. using default_deleter = default_deleter_impl<Type, std::has_trivial_default_constructor<Type>::value>;
  60.  
  61. class element_t
  62. {
  63. std::function<void(void*)> deleter;
  64. void* memory;
  65.  
  66. public:
  67. element_t() : memory(nullptr) { }
  68. element_t(element_t&&) = default;
  69. element_t(const element_t&) = delete;
  70. ~element_t() { if (deleter) deleter(memory); }
  71.  
  72. template <typename Type>
  73. operator Type&()
  74. {
  75. if (memory == nullptr)
  76. {
  77. memory = default_creator<Type>()();
  78. deleter = default_deleter<Type>();
  79. }
  80.  
  81. return *reinterpret_cast<Type*>(memory);
  82. }
  83. };
  84.  
  85. class Foo
  86. {
  87. public:
  88. using size_type = std::size_t;
  89.  
  90. private:
  91. static size_type maximum_size;
  92.  
  93. std::vector<element_t> elements;
  94.  
  95. public:
  96. Foo() = default;
  97.  
  98. template <typename Value>
  99. Value& get()
  100. {
  101. static const auto index = []() -> size_type
  102. {
  103. auto current_index = maximum_size;
  104. ++maximum_size;
  105.  
  106. return current_index;
  107. }();
  108.  
  109. if (elements.size() <= index)
  110. {
  111. elements.resize(index + 1);
  112. }
  113.  
  114. return elements[index];
  115. }
  116.  
  117. static size_type get_maximum_size()
  118. {
  119. return maximum_size;
  120. }
  121.  
  122. size_type get_current_size() const
  123. {
  124. return elements.size();
  125. }
  126. };
  127.  
  128. Foo::size_type Foo::maximum_size = 0;
  129.  
  130. struct Haha
  131. {
  132. Haha() { std::cout << "create" << std::endl; }
  133. ~Haha() { std::cout << "destroy" << std::endl; }
  134. };
  135.  
  136. int main()
  137. {
  138. {
  139. Foo a;
  140. a.get<Haha>();
  141. }
  142. }
  143.  
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
create
destroy