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
00011 #include <vcl_memory.h>
00012 #include <vcl_string.h>
00013 #include <vcl_sstream.h>
00014 #include <mbl/mbl_exception.h>
00015 #include <mbl/mbl_cloneable_ptr.h>
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
00046 template <class BASE>
00047 class mbl_cloneables_factory
00048 {
00049 private:
00050 typedef vcl_map<vcl_string, mbl_cloneable_ptr<BASE> > MAP;
00051
00052
00053 static vcl_auto_ptr<MAP> objects_;
00054
00055 private:
00056
00057
00058 static MAP &objects()
00059 {
00060 if (objects_.get() == 0)
00061 objects_.reset(new MAP);
00062
00063 return *objects_;
00064 }
00065
00066 public:
00067
00068
00069
00070 static void add(const BASE & object) { add(object, object.is_a()); }
00071
00072
00073
00074
00075 static void add(const BASE & object, const vcl_string & name)
00076 {
00077 objects()[name] = object;
00078 }
00079
00080
00081
00082 static vcl_auto_ptr<BASE > get_clone(const vcl_string & name)
00083 {
00084 typedef VCL_DISAPPEARING_TYPENAME MAP::const_iterator IT;
00085
00086 IT found = objects().find(name);
00087 const IT end = objects().end();
00088
00089 if (found == end)
00090 {
00091 vcl_ostringstream ss;
00092 IT it = objects().begin();
00093 if (!objects().empty())
00094 {
00095 ss << it->first;
00096 while ( ++it != end)
00097 ss << ", " << it->first;
00098 }
00099 mbl_exception_error(mbl_exception_no_name_in_factory(name, ss.str()));
00100 return vcl_auto_ptr<BASE >();
00101 }
00102 return vcl_auto_ptr<BASE >(found->second->clone());
00103 }
00104 };
00105
00106
00107 #define MBL_CLONEABLES_FACTORY_INSTANTIATE(T) \
00108 template <class BASE > \
00109 vcl_auto_ptr<VCL_DISAPPEARING_TYPENAME mbl_cloneables_factory<BASE >::MAP > \
00110 mbl_cloneables_factory<BASE >::objects_ = \
00111 vcl_auto_ptr<VCL_DISAPPEARING_TYPENAME mbl_cloneables_factory<BASE >::MAP >(0); \
00112 template class mbl_cloneables_factory< T >
00113
00114 #endif // mbl_cloneables_factory_h