| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- #ifndef SOPHIAR2_SMALL_OBJ_H
- #define SOPHIAR2_SMALL_OBJ_H
- #include <boost/core/noncopyable.hpp>
- #include <boost/pool/object_pool.hpp>
- #include <boost/smart_ptr/intrusive_ptr.hpp>
- #include <memory>
- #include <type_traits>
- namespace sophiar {
- template<typename DeriveT>
- struct small_obj_ref_counter : private boost::noncopyable {
- uint32_t ref_count = 0;
- };
- template<typename DeriveT>
- void intrusive_ptr_add_ref(small_obj_ref_counter<DeriveT> *pointer) {
- ++pointer->ref_count;
- }
- template<typename DeriveT>
- void intrusive_ptr_release(small_obj_ref_counter<DeriveT> *pointer) {
- if (--pointer->ref_count == 0) {
- DeriveT::allocator.destroy(static_cast<DeriveT *>(pointer));
- }
- }
- template<typename DeriveT>
- struct small_obj : public small_obj_ref_counter<DeriveT> {
- using pointer = boost::intrusive_ptr<DeriveT>;
- using allocator_type = boost::object_pool<DeriveT>;
- // static allocator_type allocator;
- inline static allocator_type allocator;
- template<typename... Args>
- std::enable_if_t<std::is_constructible_v<DeriveT, Args...>, pointer>
- static new_instance(Args &&... args) {
- auto ret_pointer = allocator.malloc();
- std::construct_at(ret_pointer, std::forward<Args>(args)...);
- return ret_pointer;
- }
- };
- // template<typename DeriveT>
- // typename small_obj<DeriveT>::allocator_type small_obj<DeriveT>::allocator{};
- #define FORWARD_CONSTRUCT(DerivedT, BaseT) \
- template<typename... Args> \
- explicit DerivedT(Args &&...args) \
- :BaseT(std::forward<Args>(args)...) { \
- static_assert(std::is_constructible_v<BaseT, Args...>); \
- }
- }
- #endif //SOPHIAR2_SMALL_OBJ_H
|