00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef UNIQUE_STORAGE_H
00013 #define UNIQUE_STORAGE_H
00014
00015 #include <vector>
00016 #include <map>
00017 #include <stdexcept>
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 template <typename I, typename V> class unique_storage {
00034
00035 public:
00036 unique_storage() {
00037
00038 values.push_back(V());
00039 }
00040
00041 virtual ~unique_storage() {}
00042
00043 typedef std::vector<V> stored_values;
00044
00045
00046 struct id_value {
00047
00048 id_value() : id(0) {}
00049
00050
00051 bool set() const {
00052 return id;
00053 }
00054
00055 bool operator<(id_value const & rhs) const {
00056 return id < rhs.id;
00057 }
00058
00059 bool operator==(id_value const & rhs) const {
00060 return id == rhs.id;
00061 }
00062
00063 bool operator!=(id_value const & rhs) const {
00064 return !(id == rhs.id);
00065 }
00066
00067 private:
00068 friend class unique_storage<I, V>;
00069
00070 typedef typename stored_values::size_type size_type;
00071
00072 explicit id_value(size_type s) : id(s) {}
00073
00074
00075 size_type id;
00076 };
00077
00078
00079
00080 id_value const create(V const & value) {
00081 typename id_map::value_type val(value, id_value(values.size()));
00082 std::pair<typename id_map::iterator, bool>
00083 inserted = ids.insert(val);
00084 if (inserted.second)
00085 values.push_back(value);
00086
00087 return inserted.first->second;
00088 }
00089
00090
00091
00092 V const & get(id_value const & id) const {
00093
00094 if (id.id < values.size())
00095 return values[id.id];
00096
00097 throw std::out_of_range("unique_storage::get(): out of bounds");
00098 }
00099
00100 private:
00101 typedef std::map<V, id_value> id_map;
00102
00103
00104 stored_values values;
00105
00106
00107 id_map ids;
00108 };
00109
00110 #endif