small_obj.hpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #ifndef SOPHIAR2_SMALL_OBJ_H
  2. #define SOPHIAR2_SMALL_OBJ_H
  3. #include <boost/core/noncopyable.hpp>
  4. #include <boost/pool/object_pool.hpp>
  5. #include <boost/smart_ptr/intrusive_ptr.hpp>
  6. #include <memory>
  7. #include <type_traits>
  8. namespace sophiar {
  9. template<typename DeriveT>
  10. struct small_obj_ref_counter : private boost::noncopyable {
  11. uint32_t ref_count = 0;
  12. };
  13. template<typename DeriveT>
  14. void intrusive_ptr_add_ref(small_obj_ref_counter<DeriveT> *pointer) {
  15. ++pointer->ref_count;
  16. }
  17. template<typename DeriveT>
  18. void intrusive_ptr_release(small_obj_ref_counter<DeriveT> *pointer) {
  19. if (--pointer->ref_count == 0) {
  20. DeriveT::allocator.destroy(static_cast<DeriveT *>(pointer));
  21. }
  22. }
  23. template<typename DeriveT>
  24. struct small_obj : public small_obj_ref_counter<DeriveT> {
  25. using pointer = boost::intrusive_ptr<DeriveT>;
  26. using allocator_type = boost::object_pool<DeriveT>;
  27. // static allocator_type allocator;
  28. inline static allocator_type allocator;
  29. template<typename... Args>
  30. std::enable_if_t<std::is_constructible_v<DeriveT, Args...>, pointer>
  31. static new_instance(Args &&... args) {
  32. auto ret_pointer = allocator.malloc();
  33. std::construct_at(ret_pointer, std::forward<Args>(args)...);
  34. return ret_pointer;
  35. }
  36. };
  37. // template<typename DeriveT>
  38. // typename small_obj<DeriveT>::allocator_type small_obj<DeriveT>::allocator{};
  39. #define FORWARD_CONSTRUCT(DerivedT, BaseT) \
  40. template<typename... Args> \
  41. explicit DerivedT(Args &&...args) \
  42. :BaseT(std::forward<Args>(args)...) { \
  43. static_assert(std::is_constructible_v<BaseT, Args...>); \
  44. }
  45. }
  46. #endif //SOPHIAR2_SMALL_OBJ_H