Go to the documentation of this file.00001
00002 #ifndef mbl_cloneables_factory_h
00003 #define mbl_cloneables_factory_h
00004
00005
00006
00007
00008
00009 #include <vcl_map.h>
00010 #include <vcl_memory.h>
00011 #include <vcl_string.h>
00012 #include <vcl_sstream.h>
00013 #include <mbl/mbl_exception.h>
00014 #include <mbl/mbl_cloneable_ptr.h>
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 template <class BASE>
00046 class mbl_cloneables_factory
00047 {
00048 private:
00049 typedef vcl_map<vcl_string, mbl_cloneable_ptr<BASE> > MAP;
00050
00051
00052 static vcl_auto_ptr<MAP> objects_;
00053
00054 private:
00055
00056
00057 static MAP &objects()
00058 {
00059 if (objects_.get() == 0)
00060 objects_.reset(new MAP);
00061
00062 return *objects_;
00063 }
00064
00065 public:
00066
00067
00068
00069 static void add(const BASE & object) { add(object, object.is_a()); }
00070
00071
00072
00073
00074 static void add(const BASE & object, const vcl_string & name)
00075 {
00076 objects()[name] = object;
00077 }
00078
00079
00080
00081 static vcl_auto_ptr<BASE > get_clone(const vcl_string & name)
00082 {
00083 typedef VCL_DISAPPEARING_TYPENAME MAP::const_iterator IT;
00084
00085 IT found = objects().find(name);
00086 const IT end = objects().end();
00087
00088 if (found == end)
00089 {
00090 vcl_ostringstream ss;
00091 IT it = objects().begin();
00092 if (!objects().empty())
00093 {
00094 ss << it->first;
00095 while ( ++it != end)
00096 ss << ", " << it->first;
00097 }
00098 mbl_exception_error(mbl_exception_no_name_in_factory(name, ss.str()));
00099 return vcl_auto_ptr<BASE >();
00100 }
00101 return vcl_auto_ptr<BASE >(found->second->clone());
00102 }
00103 };
00104
00105
00106 #define MBL_CLONEABLES_FACTORY_INSTANTIATE(T) \
00107 template <class BASE > \
00108 vcl_auto_ptr<VCL_DISAPPEARING_TYPENAME mbl_cloneables_factory<BASE >::MAP > \
00109 mbl_cloneables_factory<BASE >::objects_ = \
00110 vcl_auto_ptr<VCL_DISAPPEARING_TYPENAME mbl_cloneables_factory<BASE >::MAP >(0); \
00111 template class mbl_cloneables_factory< T >
00112
00113 #endif // mbl_cloneables_factory_h