| 1 | // file : xsd/cxx/tree/stream-insertion-map.hxx |
|---|
| 2 | // author : Boris Kolpackov <boris@codesynthesis.com> |
|---|
| 3 | // copyright : Copyright (c) 2005-2008 Code Synthesis Tools CC |
|---|
| 4 | // license : GNU GPL v2 + exceptions; see accompanying LICENSE file |
|---|
| 5 | |
|---|
| 6 | #ifndef XSD_CXX_TREE_STREAM_INSERTION_MAP_HXX |
|---|
| 7 | #define XSD_CXX_TREE_STREAM_INSERTION_MAP_HXX |
|---|
| 8 | |
|---|
| 9 | #include <map> |
|---|
| 10 | #include <string> |
|---|
| 11 | #include <typeinfo> |
|---|
| 12 | |
|---|
| 13 | #include <xsd/cxx/tree/elements.hxx> |
|---|
| 14 | #include <xsd/cxx/tree/ostream.hxx> |
|---|
| 15 | #include <xsd/cxx/xml/qualified-name.hxx> |
|---|
| 16 | |
|---|
| 17 | namespace xsd |
|---|
| 18 | { |
|---|
| 19 | namespace cxx |
|---|
| 20 | { |
|---|
| 21 | namespace tree |
|---|
| 22 | { |
|---|
| 23 | template <typename S, typename C> |
|---|
| 24 | struct stream_insertion_map |
|---|
| 25 | { |
|---|
| 26 | typedef std::type_info type_id; |
|---|
| 27 | typedef xml::qualified_name<C> qualified_name; |
|---|
| 28 | typedef void (*inserter) (ostream<S>&, const type&); |
|---|
| 29 | |
|---|
| 30 | stream_insertion_map (); |
|---|
| 31 | |
|---|
| 32 | void |
|---|
| 33 | register_type (const type_id&, |
|---|
| 34 | const qualified_name& name, |
|---|
| 35 | inserter, |
|---|
| 36 | bool override = true); |
|---|
| 37 | |
|---|
| 38 | void |
|---|
| 39 | insert (ostream<S>&, const type&); |
|---|
| 40 | |
|---|
| 41 | public: |
|---|
| 42 | struct type_info |
|---|
| 43 | { |
|---|
| 44 | type_info (const qualified_name& name, |
|---|
| 45 | typename stream_insertion_map::inserter inserter) |
|---|
| 46 | : name_ (name), inserter_ (inserter) |
|---|
| 47 | { |
|---|
| 48 | } |
|---|
| 49 | |
|---|
| 50 | const qualified_name& |
|---|
| 51 | name () const |
|---|
| 52 | { |
|---|
| 53 | return name_; |
|---|
| 54 | } |
|---|
| 55 | |
|---|
| 56 | typename stream_insertion_map::inserter |
|---|
| 57 | inserter () const |
|---|
| 58 | { |
|---|
| 59 | return inserter_; |
|---|
| 60 | } |
|---|
| 61 | |
|---|
| 62 | // For std::map. |
|---|
| 63 | // |
|---|
| 64 | type_info () |
|---|
| 65 | : name_ (std::basic_string<C> (), std::basic_string<C> ()), |
|---|
| 66 | inserter_ (0) |
|---|
| 67 | { |
|---|
| 68 | } |
|---|
| 69 | |
|---|
| 70 | private: |
|---|
| 71 | qualified_name name_; |
|---|
| 72 | typename stream_insertion_map::inserter inserter_; |
|---|
| 73 | }; |
|---|
| 74 | |
|---|
| 75 | public: |
|---|
| 76 | const type_info* |
|---|
| 77 | find (const type_id&) const; |
|---|
| 78 | |
|---|
| 79 | private: |
|---|
| 80 | struct type_id_comparator |
|---|
| 81 | { |
|---|
| 82 | bool |
|---|
| 83 | operator() (const type_id* x, const type_id* y) const |
|---|
| 84 | { |
|---|
| 85 | return x->before (*y); |
|---|
| 86 | } |
|---|
| 87 | }; |
|---|
| 88 | |
|---|
| 89 | typedef |
|---|
| 90 | std::map<const type_id*, type_info, type_id_comparator> |
|---|
| 91 | type_map; |
|---|
| 92 | |
|---|
| 93 | type_map type_map_; |
|---|
| 94 | }; |
|---|
| 95 | |
|---|
| 96 | // |
|---|
| 97 | // |
|---|
| 98 | template<unsigned long id, typename S, typename C> |
|---|
| 99 | struct stream_insertion_plate |
|---|
| 100 | { |
|---|
| 101 | static stream_insertion_map<S, C>* map; |
|---|
| 102 | static unsigned long count; |
|---|
| 103 | |
|---|
| 104 | stream_insertion_plate (); |
|---|
| 105 | ~stream_insertion_plate (); |
|---|
| 106 | }; |
|---|
| 107 | |
|---|
| 108 | template<unsigned long id, typename S, typename C> |
|---|
| 109 | stream_insertion_map<S, C>* stream_insertion_plate<id, S, C>::map = 0; |
|---|
| 110 | |
|---|
| 111 | template<unsigned long id, typename S, typename C> |
|---|
| 112 | unsigned long stream_insertion_plate<id, S, C>::count = 0; |
|---|
| 113 | |
|---|
| 114 | |
|---|
| 115 | // |
|---|
| 116 | // |
|---|
| 117 | template<unsigned long id, typename S, typename C> |
|---|
| 118 | inline stream_insertion_map<S, C>& |
|---|
| 119 | stream_insertion_map_instance () |
|---|
| 120 | { |
|---|
| 121 | return *stream_insertion_plate<id, S, C>::map; |
|---|
| 122 | } |
|---|
| 123 | |
|---|
| 124 | // |
|---|
| 125 | // |
|---|
| 126 | template<typename S, typename X> |
|---|
| 127 | void |
|---|
| 128 | inserter_impl (ostream<S>&, const type&); |
|---|
| 129 | |
|---|
| 130 | template<unsigned long id, typename S, typename C, typename X> |
|---|
| 131 | struct stream_insertion_initializer |
|---|
| 132 | { |
|---|
| 133 | stream_insertion_initializer (const C* name, const C* ns); |
|---|
| 134 | }; |
|---|
| 135 | } |
|---|
| 136 | } |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | #include <xsd/cxx/tree/stream-insertion-map.txx> |
|---|
| 140 | |
|---|
| 141 | #endif // XSD_CXX_TREE_STREAM_INSERTION_MAP_HXX |
|---|