00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef avro_NodeConcepts_hh__
00020 #define avro_NodeConcepts_hh__
00021
00022 #include <vector>
00023 #include <map>
00024 #include "Config.hh"
00025 #include "Exception.hh"
00026
00027 namespace avro {
00028
00029
00046
00047 namespace concepts {
00048
00049 template <typename Attribute>
00050 struct NoAttribute
00051 {
00052 static const bool hasAttribute = false;
00053
00054 size_t size() const {
00055 return 0;
00056 }
00057
00058 void add( const Attribute &attr) {
00059
00060
00061
00062 throw Exception("This type does not have attribute");
00063 }
00064
00065 const Attribute &get(size_t index = 0) const {
00066
00067
00068
00069 throw Exception("This type does not have attribute");
00070
00071 static const Attribute empty = Attribute();
00072 return empty;
00073 }
00074
00075 };
00076
00077 template<typename Attribute>
00078 struct SingleAttribute
00079 {
00080 static const bool hasAttribute = true;
00081
00082 SingleAttribute() : attr_(), size_(0)
00083 { }
00084
00085 SingleAttribute(const Attribute& a) : attr_(a), size_(1) { }
00086
00087 SingleAttribute(const SingleAttribute<Attribute> &rhs) :
00088 attr_(rhs.attr_), size_(rhs.size_)
00089 { }
00090
00091
00092 SingleAttribute(const NoAttribute<Attribute> &rhs) :
00093 attr_(), size_(0)
00094 { }
00095
00096 size_t size() const {
00097 return size_;
00098 }
00099
00100 void add(const Attribute &attr) {
00101 if(size_ == 0) {
00102 size_ = 1;
00103 }
00104 else {
00105 throw Exception("SingleAttribute can only be set once");
00106 }
00107 attr_ = attr;
00108 }
00109
00110 const Attribute &get(size_t index = 0) const {
00111 if(index != 0) {
00112 throw Exception("SingleAttribute has only 1 value");
00113 }
00114 return attr_;
00115 }
00116
00117 private:
00118
00119 template<typename T> friend struct MultiAttribute;
00120
00121 Attribute attr_;
00122 int size_;
00123 };
00124
00125 template<typename Attribute>
00126 struct MultiAttribute
00127 {
00128 static const bool hasAttribute = true;
00129
00130 MultiAttribute()
00131 { }
00132
00133
00134
00135 MultiAttribute(const SingleAttribute<Attribute> &rhs)
00136 {
00137
00138
00139 attrs_.reserve(2);
00140 attrs_.push_back(rhs.attr_);
00141 }
00142
00143 MultiAttribute(const MultiAttribute<Attribute> &rhs) :
00144 attrs_(rhs.attrs_)
00145 { }
00146
00147 MultiAttribute(const NoAttribute<Attribute> &rhs)
00148 {}
00149
00150 size_t size() const {
00151 return attrs_.size();
00152 }
00153
00154 void add(const Attribute &attr) {
00155 attrs_.push_back(attr);
00156 }
00157
00158 const Attribute &get(size_t index = 0) const {
00159 return attrs_.at(index);
00160 }
00161
00162 Attribute &get(size_t index) {
00163 return attrs_.at(index);
00164 }
00165
00166 private:
00167
00168 std::vector<Attribute> attrs_;
00169 };
00170
00171
00172 template<typename T>
00173 struct NameIndexConcept {
00174
00175 bool lookup(const std::string &name, size_t &index) const {
00176 throw Exception("Name index does not exist");
00177 return 0;
00178 }
00179
00180 bool add(const::std::string &name, size_t index) {
00181 throw Exception("Name index does not exist");
00182 return false;
00183 }
00184 };
00185
00186 template<>
00187 struct NameIndexConcept < MultiAttribute<std::string> >
00188 {
00189 typedef std::map<std::string, size_t> IndexMap;
00190
00191 bool lookup(const std::string &name, size_t &index) const {
00192 IndexMap::const_iterator iter = map_.find(name);
00193 if(iter == map_.end()) {
00194 return false;
00195 }
00196 index = iter->second;
00197 return true;
00198 }
00199
00200 bool add(const::std::string &name, size_t index) {
00201 bool added = false;
00202 IndexMap::iterator lb = map_.lower_bound(name);
00203 if(lb == map_.end() || map_.key_comp()(name, lb->first)) {
00204 map_.insert(lb, IndexMap::value_type(name, index));
00205 added = true;
00206 }
00207 return added;
00208 }
00209
00210 private:
00211
00212 IndexMap map_;
00213 };
00214
00215 }
00216 }
00217
00218 #endif