// // Copyright (c) 2012-2020 Kris Jusiak (kris at jusiak dot net) // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // //<- #include #include //-> #include namespace di = boost::di; //<- BOOST_DI_NAMESPACE_BEGIN namespace wrappers { template struct unique> { using scope = TScope; template inline operator I() const noexcept { return *object; } template inline operator I*() noexcept { return object.release(); } template inline operator const I*() noexcept { return object.release(); } template inline operator std::shared_ptr() noexcept { return {object.release(), object.get_deleter()}; } template inline operator std::unique_ptr() noexcept { return static_cast&&>(object); } std::unique_ptr object; }; } BOOST_DI_NAMESPACE_END struct interface { virtual ~interface() noexcept = default; }; struct implementation : interface {}; /**/ struct pool_allocator { template static di::aux::owner allocate(); static void deallocate(di::aux::owner); }; template di::aux::owner pool_allocator::allocate() { return (T*)::operator new(sizeof(T)); } void pool_allocator::deallocate(di::aux::owner ptr) { return ::operator delete(ptr); } struct pool_deleter { void operator()(di::aux::owner ptr) const noexcept { pool_allocator::deallocate(ptr); } }; //-> /**/ struct pool_provider { template struct is_creatable { static constexpr auto value = true; }; template auto get(const TInitialization& // direct/uniform , const TMemory& // stack/heap , TArgs&&... args) const { auto memory = pool_allocator::allocate(); return std::unique_ptr{new (memory) T(std::forward(args)...)}; } }; /**/ class config : public di::config { public: static auto provider(...) noexcept { return pool_provider{}; } }; /**/ struct example { explicit example(int i, std::unique_ptr up, std::shared_ptr sp) { assert(i == 42); assert(dynamic_cast(up.get())); assert(dynamic_cast(sp.get())); } }; #if defined(_MSC_VER) int main() {} #else int main() { /*<>*/ // clang-format off auto injector = di::make_injector( di::bind().to(42) , di::bind().to() ); // clang-format on /*<>*/ injector.create(); } #endif