[bfdf0c]: libutil++ / unique_storage.h Maximize Restore History

Download this file

unique_storage.h    114 lines (87 with data), 2.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* @file unique_storage.h
* Unique storage of values
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author Philippe Elie
* @author John Levon
*/
#ifndef UNIQUE_STORAGE_H
#define UNIQUE_STORAGE_H
#include <vector>
#include <map>
#include <stdexcept>
/**
* Store values such that only one copy of the value
* is ever stored.
*
* I is an arbitrary typename that's never
* used.
*
* It is a required parameter in order to enforce
* type-safety for a collection.
*
* The value type "V" must be default-constructible,
* and this is the value returned by a stored id_value
* where .set() is false
*/
template <typename I, typename V> class unique_storage {
public:
unique_storage() {
// id 0
values.push_back(V());
}
virtual ~unique_storage() {}
typedef std::vector<V> stored_values;
/// the actual ID type
struct id_value {
/// id == 0 means "empty" / "undefined"
id_value() : id(0) {}
/// does this ID map to a non-default value ?
bool set() const {
return id;
}
bool operator<(id_value const & rhs) const {
return id < rhs.id;
}
bool operator==(id_value const & rhs) const {
return id == rhs.id;
}
bool operator!=(id_value const & rhs) const {
return !(id == rhs.id);
}
private:
friend class unique_storage<I, V>;
typedef typename stored_values::size_type size_type;
explicit id_value(size_type s) : id(s) {}
/// actual ID value
size_type id;
};
/// ensure this value is available
id_value const create(V const & value) {
typename id_map::const_iterator cit = ids.find(value);
if (cit == ids.end()) {
id_value const id(values.size());
values.push_back(value);
ids[value] = id;
return id;
}
return cit->second;
}
/// return the stored value for the given ID
V const & get(id_value const & id) const {
// some stl lack at(), so we emulate it
if (id.id < values.size())
return values[id.id];
throw std::out_of_range("unique_storage::get(): out of bounds");
}
private:
typedef std::map<V, id_value> id_map;
/// the contained values
stored_values values;
/// map from ID to value
id_map ids;
};
#endif /* !UNIQUE_STORAGE_H */