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