Avro C++
NodeConcepts.hh
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * https://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #ifndef avro_NodeConcepts_hh__
20 #define avro_NodeConcepts_hh__
21 
22 #include "Config.hh"
23 
24 #include <vector>
25 #include <map>
26 #include "Exception.hh"
27 
28 namespace avro {
29 
30 
47 
48 namespace concepts {
49 
50 template <typename Attribute>
52 {
53  static const bool hasAttribute = false;
54 
55  size_t size() const {
56  return 0;
57  }
58 
59  void add( const Attribute &attr) {
60  // There must be an add function for the generic NodeImpl, but the
61  // Node APIs ensure that it is never called, the throw here is
62  // just in case
63  throw Exception("This type does not have attribute");
64  }
65 
66  const Attribute &get(size_t index = 0) const {
67  // There must be an get function for the generic NodeImpl, but the
68  // Node APIs ensure that it is never called, the throw here is
69  // just in case
70  throw Exception("This type does not have attribute");
71  // even though this code is unreachable the compiler requires it
72  static const Attribute empty = Attribute();
73  return empty;
74  }
75 
76  Attribute &get(size_t index = 0) {
77  // There must be an get function for the generic NodeImpl, but the
78  // Node APIs ensure that it is never called, the throw here is
79  // just in case
80  throw Exception("This type does not have attribute");
81  }
82 
83 };
84 
85 template<typename Attribute>
87 {
88  static const bool hasAttribute = true;
89 
90  SingleAttribute() : attr_()
91  { }
92 
93  SingleAttribute(const Attribute& a) : attr_(a) { }
94  // copy constructing from another single attribute is allowed
96  attr_(rhs.attr_)
97  { }
98 
99  // copy constructing from a no attribute is allowed
101  attr_()
102  { }
103 
104  size_t size() const {
105  return 1;
106  }
107 
108  void add(const Attribute &attr) {
109  attr_ = attr;
110  }
111 
112  const Attribute &get(size_t index = 0) const {
113  if (index != 0) {
114  throw Exception("SingleAttribute has only 1 value");
115  }
116  return attr_;
117  }
118 
119  Attribute &get(size_t index = 0) {
120  if (index != 0) {
121  throw Exception("SingleAttribute has only 1 value");
122  }
123  return attr_;
124  }
125 
126 private:
127  template<typename T> friend struct MultiAttribute;
128  Attribute attr_;
129 };
130 
131 template<typename Attribute>
133 {
134  static const bool hasAttribute = true;
135 
137  { }
138 
139  // copy constructing from another single attribute is allowed, it
140  // pushes the attribute
142  {
143  // since map is the only type that does this we know it's
144  // final size will be two, so reserve
145  attrs_.reserve(2);
146  attrs_.push_back(rhs.attr_);
147  }
148 
150  attrs_(rhs.attrs_)
151  { }
152 
154  {}
155 
156  size_t size() const {
157  return attrs_.size();
158  }
159 
160  void add(const Attribute &attr) {
161  attrs_.push_back(attr);
162  }
163 
164  const Attribute &get(size_t index = 0) const {
165  return attrs_.at(index);
166  }
167 
168  Attribute &get(size_t index) {
169  return attrs_.at(index);
170  }
171 
172  private:
173 
174  std::vector<Attribute> attrs_;
175 };
176 
177 
178 template<typename T>
180 
181  bool lookup(const std::string &name, size_t &index) const {
182  throw Exception("Name index does not exist");
183  return 0;
184  }
185 
186  bool add(const::std::string &name, size_t index) {
187  throw Exception("Name index does not exist");
188  return false;
189  }
190 };
191 
192 template<>
194 {
195  typedef std::map<std::string, size_t> IndexMap;
196 
197  bool lookup(const std::string &name, size_t &index) const {
198  IndexMap::const_iterator iter = map_.find(name);
199  if(iter == map_.end()) {
200  return false;
201  }
202  index = iter->second;
203  return true;
204  }
205 
206  bool add(const::std::string &name, size_t index) {
207  bool added = false;
208  IndexMap::iterator lb = map_.lower_bound(name);
209  if(lb == map_.end() || map_.key_comp()(name, lb->first)) {
210  map_.insert(lb, IndexMap::value_type(name, index));
211  added = true;
212  }
213  return added;
214  }
215 
216  private:
217 
218  IndexMap map_;
219 };
220 
221 } // namespace concepts
222 } // namespace avro
223 
224 #endif
A bunch of templates and specializations for encoding and decoding specific types.
Definition: AvroParse.hh:30
Definition: Node.hh:202
Definition: NodeConcepts.hh:132
Definition: NodeConcepts.hh:86
Definition: NodeConcepts.hh:179
Wrapper for std::runtime_error that provides convenience constructor for boost::format objects...
Definition: Exception.hh:31
Definition: NodeConcepts.hh:51