Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef __BASE__FACTORY_H__ 6 : #define __BASE__FACTORY_H__ 7 : 8 : // in Boost this macro defaults to 6 but we're defining FACTORY_TYPE_N8 9 : // so we need to define it manually 10 : #define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 8 11 : 12 : #include <functional> 13 : #include <iostream> 14 : 15 : #include <boost/function.hpp> 16 : #include <boost/functional/factory.hpp> 17 : #include <boost/functional/forward_adapter.hpp> 18 : #include <boost/type_traits/is_same.hpp> 19 : #include <boost/utility/enable_if.hpp> 20 : 21 : #include "base/util.h" 22 : 23 : struct StaticObjectFactory { 24 : 25 : template<class Base, class ... Args> 26 : struct FactoryTypes 27 : { 28 : using BaseType = Base; 29 : using BasePointer = BaseType *; 30 : using Signature = BasePointer(Args...); 31 : using FunctionType = std::function<Signature>; 32 : }; 33 : 34 : template<class Base, class Impl> 35 : struct Creator { 36 : template<class ...Args> static 37 : typename FactoryTypes<Base,Args...>::BasePointer 38 39254 : new_instance(Args &&... args) { 39 : return static_cast<typename 40 : FactoryTypes<Base,Args...>::BasePointer> 41 39254 : (new Impl(args...)); 42 : }; 43 : }; 44 : 45 : template<class Base, class Impl, class ... Args> 46 : static typename FactoryTypes<Base, Args...>::BasePointer 47 578553 : NewInstance(Args ...args) 48 : { 49 : return static_cast<typename StaticObjectFactory::FactoryTypes 50 578553 : <Base, Args...>::BasePointer> (new Impl (args...)); 51 : }; 52 : 53 : template<class Base, class ... Args> 54 : struct DefaultLink; 55 : 56 : template<class Base, class ... Args> 57 : struct FactoryRecord 58 : { 59 : using Signature = typename FactoryTypes<Base, Args...>::Signature; 60 : using FunctionType = typename FactoryTypes<Base, Args...>::FunctionType; 61 : using DefaultLinkType = DefaultLink<Base, Args...>; 62 : 63 : static FunctionType create_func_; 64 : static DefaultLinkType default_link_; 65 : }; 66 : 67 : template<class Base, class Impl, class ... Args> 68 6282 : static void LinkImpl() 69 : { 70 6282 : FactoryRecord<Base, Args...>::create_func_ = 71 : StaticObjectFactory::NewInstance<Base, Impl, Args...>; 72 6282 : }; 73 : 74 : template<class Base, int p> 75 : struct ParameterCastTo { 76 : }; 77 : 78 : template<class Base, class ... Args> 79 : struct DefaultLink 80 : { 81 5369 : DefaultLink() 82 : { 83 5369 : StaticObjectFactory::LinkImpl<Base, Base, Args...>(); 84 5369 : } 85 : }; 86 : 87 : template<class Base, class ... Args> 88 : static typename FactoryTypes<Base, Args...>::BasePointer 89 571298 : Create(Args ...args) { 90 571298 : if (!bool(FactoryRecord<Base, Args...>::create_func_)) { 91 0 : return nullptr; 92 : } 93 571301 : return FactoryRecord<Base, Args...>::create_func_(args...); 94 : }; 95 : 96 : template<class BaseType, int par, class ...Args> 97 : static typename FactoryTypes<BaseType, Args...>::BasePointer 98 39254 : Create(Args &&...args) { 99 : return Creator< 100 : BaseType, 101 39254 : typename ParameterCastTo<BaseType,par>::ImplType>::new_instance(args...); 102 : }; 103 : }; 104 : 105 : #endif