1 #ifndef LIBJMMCG_CORE_FACTORY_HPP 2 #define LIBJMMCG_CORE_FACTORY_HPP 3 4 /****************************************************************************** 5 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/core/factory.hpp 2055 2017-05-13 19:35:47Z jmmcg $ 6 ** 7 ** Copyright © 2005 by J.M.McGuiness, coder@hussar.me.uk 8 ** 9 ** This library is free software; you can redistribute it and/or 10 ** modify it under the terms of the GNU Lesser General Public 11 ** License as published by the Free Software Foundation; either 12 ** version 2.1 of the License, or (at your option) any later version. 13 ** 14 ** This library is distributed in the hope that it will be useful, 15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 ** Lesser General Public License for more details. 18 ** 19 ** You should have received a copy of the GNU Lesser General Public 20 ** License along with this library; if not, write to the Free Software 21 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 #include "exception.hpp" 25 #include "multimap.hpp" 26 #include "shared_ptr.hpp" 27 28 namespace jmmcg { namespace factory { 29 30 /// The error information if a requested key-type is not registered with the factory. 31 template< 32 typename ID_, ///< The type of the key. 33 class Ret_, ///< The type that the key should have returned. 34 class Excpt_ ///< The base exception class from which this should derive to place it in the appropriate position in the exception hierarchy. 35 > 36 struct not_found { 37 typedef Excpt_ exception_type; 38 39 /// This function throws the above exception for the specified ID_ type. 40 static Ret_ __fastcall execute(const ID_ &); 41 }; 42 43 /// The base factory-type. 44 /** 45 Note that this class is threading-agnostic. 46 */ 47 template< 48 typename ID_, ///< The key-type of the factory. 49 class Obj_, ///< The type of item to be returned by the key-type. 50 class Except_, ///< The exception-type to root the exception hierarchy onto. 51 class Ret_, ///< Exactly how the item returned by the key-type should be returned, e.g. via transfer of ownership. 52 class NotFound_, ///< The type of exception thrown if the specified key-type is not registered with the factory. 53 typename CreatFn_, ///< Some kind of function or functor that is used to create the item to be returned from a specific key-type. 54 class Cont_ ///< The type of associative container that should be used by the factory for identifying the method by which the specified instance of key-type should return the value-type. 55 > 56 class base : protected non_copyable { 57 public: 58 typedef Cont_ container_type; 59 typedef typename container_type::key_type id_type; 60 typedef typename container_type::value_type value_type; 61 typedef typename container_type::mapped_type createable_type; 62 typedef typename container_type::mapped_type mapped_type; 63 typedef typename container_type::size_type size_type; 64 typedef Ret_ created_type; 65 66 virtual __stdcall ~base(void); 67 68 /// Register a specific key & manufacturing method with the factory. 69 bool __fastcall insert(const value_type &); 70 /// Register a specific key & manufacturing method with the factory. 71 bool __fastcall insert(const id_type &,const createable_type &); 72 /// Unregister a specific key from the factory. 73 const typename container_type::size_type __fastcall erase(const id_type &id) { 74 return createables_.erase(id); 75 } 76 /// Return true if that key has been registered with the factory. 77 bool __fastcall find(const id_type &) const; 78 /// Return true if any key has been registered with the factory. 79 bool __fastcall empty(void) const noexcept(true); 80 /// Return the total number of unique keys registered with the factory. 81 const size_type __fastcall size(void) const noexcept(true); 82 /// Reserve capacity for a specified number of keys with the factory. 83 void __fastcall reserve(const size_type); 84 85 /// Access the internal associative collection used to store the keys and methods for creating the return items. 86 const container_type & __fastcall createables(void) const noexcept(true); 87 /// Access the internal associative collection used to store the keys and methods for creating the return items. 88 container_type & __fastcall createables(void) noexcept(true); 89 90 protected: 91 container_type createables_; 92 93 __stdcall base(void); 94 }; 95 96 /// A factory that manufactures a new, unique instance of the specified return-type for a specified key that has been registered with the factory. 97 /** 98 Note that this class is not thread-safe by default, at a minimum the container would need to be thread-safe. 99 */ 100 template< 101 typename ID_, ///< The key-type of the factory. 102 class Obj_, ///< The type of item to be returned by the key-type. 103 class Except_, ///< The exception-type to root the exception hierarchy onto. 104 class Ret_=std::unique_ptr<Obj_>, ///< Exactly how the item returned by the key-type should be returned, e.g. via transfer of ownership. 105 class NotFound_=not_found<ID_, Ret_, Except_>, ///< The type of exception thrown if the specified key-type is not registered with the factory. 106 typename CreatFn_=Ret_ (__fastcall *)(void), ///< The type of method by which the factory may manufacture a new, unique instance of the specified item to be returned. 107 class Cont_=jmmcg::rapid_insert_lookup::multimap<ID_, CreatFn_> ///< The type of associative container that should be used by the factory for identifying the method by which the specified instance of key-type should return the value-type. 108 > 109 class creator : public base<ID_, Obj_, Except_, Ret_, NotFound_, CreatFn_, Cont_> { 110 public: 111 typedef base<ID_, Obj_, Except_, Ret_, NotFound_, CreatFn_, Cont_> base_t; 112 typedef typename base_t::id_type id_type; 113 typedef typename base_t::created_type created_type; 114 115 constexpr __stdcall creator(void); 116 virtual __stdcall ~creator(void); 117 118 /// Returns a new, unique new, unique instance of the specified return-type for a specified key that has been registered with the factory. 119 virtual created_type __fastcall make(const id_type &id) const; 120 }; 121 122 /// A factory that manufactures a clone of an instance of the specified return-type for a specified key that has been registered with the factory. 123 /** 124 Note that this class is not thread-safe by default, at a minimum the container and shared pointer-type would need to be thread-safe. 125 */ 126 template< 127 typename ID_, ///< The key-type of the factory. 128 class Obj_, ///< The type of item to be returned by the key-type. 129 class Except_, ///< The exception-type to root the exception hierarchy onto. 130 class Ret_=std::unique_ptr<Obj_>, ///< Exactly how the item returned by the key-type should be returned, e.g. via transfer of ownership. 131 class NotFound_=not_found<ID_, Ret_, Except_>, ///< The type of exception thrown if the specified key-type is not registered with the factory. 132 typename CreatFn_=Ret_ (__fastcall *)(const Obj_ &), ///< Return a copy of the instance of the specified item to be returned. 133 class Cont_=jmmcg::rapid_insert_lookup::multimap<ID_, std::pair<jmmcg::shared_ptr<Obj_, jmmcg::ppd::api_lock_traits<jmmcg::ppd::platform_api, jmmcg::ppd::sequential_mode>>, CreatFn_> ///< The type of associative container that should be used by the factory for identifying the method by which the specified instance of key-type should return the value-type. 134 > 135 > 136 class clone : public base<ID_, Obj_, Except_, Ret_, NotFound_, CreatFn_, Cont_> { 137 public: 138 typedef base<ID_, Obj_, Except_, Ret_, NotFound_, CreatFn_, Cont_> base_t; 139 typedef typename base_t::id_type id_type; 140 typedef typename base_t::createable_type createable_type; 141 typedef typename base_t::created_type created_type; 142 typedef typename Cont_::mapped_type::first_type::value_type::lock_traits lock_traits; 143 144 constexpr __stdcall clone(); 145 virtual __stdcall ~clone(); 146 147 /// Returns a clone of an instance of the specified return-type for a specified key that has been registered with the factory. 148 virtual created_type __fastcall make(const id_type &) const; 149 }; 150 151 } } 152 153 #include "factory_impl.hpp" 154 155 #endif