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