Еще один пример того, как C++ные шаблоны позволяют избавиться от дублирования кода.
Задача метода create_mchain в том, чтобы проанализировав несколько аргументов создать экземпляр шаблонного класса mchain_template с нужным набором шаблонных параметров. Слева код, который был написан сходу, с применением копипасты. Справа -- результат простого рефакторинга.
mchain mbox_core_t::create_mchain( environment_t & env, const mchain_params & params ) { using namespace so_5::mchain_props; using namespace so_5::mchain_props::details; using namespace so_5::rt::impl::msg_tracing_helpers; auto id = ++m_mbox_id_counter; if( !m_tracer ) { if( params.capacity().unlimited() ) return mchain{ new mchain_template< unlimited_demand_queue, mchain_tracing_disabled_base >{ env, id, params.capacity() } }; else if( storage_memory::dynamic == params.capacity().memory() ) return mchain{ new mchain_template< limited_dynamic_demand_queue, mchain_tracing_disabled_base >{ env, id, params.capacity() } }; else return mchain{ new mchain_template< limited_preallocated_demand_queue, mchain_tracing_disabled_base >{ env, id, params.capacity() } }; } else { if( params.capacity().unlimited() ) return mchain{ new mchain_template< unlimited_demand_queue, mchain_tracing_enabled_base >{ env, id, params.capacity(), *m_tracer } }; else if( storage_memory::dynamic == params.capacity().memory() ) return mchain{ new mchain_template< limited_dynamic_demand_queue, mchain_tracing_enabled_base >{ env, id, params.capacity(), *m_tracer } }; else return mchain{ new mchain_template< limited_preallocated_demand_queue, mchain_tracing_enabled_base >{ env, id, params.capacity(), *m_tracer } }; } } |
namespace { template< typename Q, typename... A > mchain make_mchain( so_5::msg_tracing::tracer_t * tracer, A &&... args ) { using namespace so_5::mchain_props; using namespace so_5::rt::impl::msg_tracing_helpers; using D = mchain_tracing_disabled_base; using E = mchain_tracing_enabled_base; if( tracer ) return mchain{ new mchain_template< Q, E >{ std::forward<A>(args)..., *tracer } }; else return mchain{ new mchain_template< Q, D >{ std::forward<A>(args)... } }; } } /* namespace anonymous */ mchain mbox_core_t::create_mchain( environment_t & env, const mchain_params & params ) { using namespace so_5::mchain_props; using namespace so_5::mchain_props::details; auto id = ++m_mbox_id_counter; if( params.capacity().unlimited() ) return make_mchain< unlimited_demand_queue >( m_tracer, env, id, params.capacity() ); else if( storage_memory::dynamic == params.capacity().memory() ) return make_mchain< limited_dynamic_demand_queue >( m_tracer, env, id, params.capacity() ); else return make_mchain< limited_preallocated_demand_queue >( m_tracer, env, id, params.capacity() ); } |
Комментариев нет:
Отправить комментарий