1 // This is brl/bbas/brdb/brdb_value.h
2 #ifndef brdb_value_h_
3 #define brdb_value_h_
4 //:
5 // \file
6 // \brief The database value class
7 // \author Matt Leotta
8 // \date January 24, 2005
9 //
10 // \verbatim
11 //  Modifications
12 //   Apr 4, 2007 - Yong Zhao - Make it work with the whole database initially based on Matt's sketch.
13 // \endverbatim
14 
15 #include <string>
16 #include <map>
17 #include <iostream>
18 #include <utility>
19 #include <brdb/brdb_value_sptr.h>
20 #include <cassert>
21 #include <vbl/vbl_ref_count.h>
22 #ifdef _MSC_VER
23 #  include <vcl_msvc_warnings.h>
24 #endif
25 #include <vsl/vsl_binary_io.h>
26 
27 // forward declaration
28 template< class T > class brdb_value_t;
29 
30 //: This abstract class is the base class for database values
31 class brdb_value : public vbl_ref_count
32 {
33  public:
34 
35   //: Destructor
36   ~brdb_value() override = default;
37 
38   //: Return the actual value
39   template< class T >
val()40   T val() const
41   {
42     const brdb_value_t<T>* type_val = dynamic_cast<const brdb_value_t<T>*>(this);
43     assert(type_val);
44     return type_val->value();
45   }
46 
47 
48   //: Assignment operator
49   template< class T >
50   brdb_value& operator = (const T& rhs)
51   {
52     assert(this->is_a() == brdb_value_t<T>::type());
53     this->assign(brdb_value_t<T>(rhs));
54     return *this;
55   }
56 
57   //: Create a copy of the object on the heap.
58   // The caller is responsible for deletion
59   virtual brdb_value* clone() const = 0;
60 
61   //: Return the string identifying this class
62   virtual std::string is_a() const = 0;
63 
64   //: Test for equality under polymorphism
65   virtual bool eq(const brdb_value& other) const = 0;
66 
67   //: Test for inequality (less than) under polymorphism
68   virtual bool lt(const brdb_value& other) const = 0;
69 
70   //: Assign the value of /p other to this if the types are the same
71   virtual bool assign(const brdb_value& other) = 0;
72 
73   //: Print out the value
74   virtual void print() const = 0;
75 
76   //: Return a const reference to the global registry of database value classes
registry()77   static std::map<std::string, const brdb_value*> const & registry() { return mut_registry(); }
78 
79   //: Create static instances of this struct to register a database value class
80   struct registrar{
81     registrar(const brdb_value* exemplar);
82   };
83 
84   friend struct registrar;
85 
86   //---------------------------------------------------------------------------
87   // Binary I/O functions
88 
89   //: binary io read value only
90   //  Handles only the value (without version or type info)
b_read_value(vsl_b_istream &)91   virtual void b_read_value(vsl_b_istream&)
92   {
93     std::cout << "Warning: calling binary read on parent value class, this value is not being read" << std::endl;
94   }
95 
96   //: binary io write value only
97   //  Handles only the value (without version or type info)
b_write_value(vsl_b_ostream &)98   virtual void b_write_value(vsl_b_ostream&) const
99   {
100     std::cout << "Warning: calling binary write on parent value class, this value is not being saved" << std::endl;
101   }
102 
103 
104  protected:
105   //: Constructor
106   brdb_value() = default;
107   //: Copy Constructor
brdb_value(const brdb_value &)108   brdb_value(const brdb_value&) : vbl_ref_count() {}
109 
110  private:
111   //: Return a reference to the global registry of database value classes
112   static std::map<std::string, const brdb_value*> & mut_registry();
113 };
114 
115 //: Equals operator
116 inline bool operator == (const brdb_value& lhs,
117                          const brdb_value& rhs)
118 {
119   assert(lhs.is_a() == rhs.is_a());
120   return lhs.eq(rhs);
121 }
122 
123 //: Not Equal operator
124 inline bool operator != (const brdb_value& lhs,
125                          const brdb_value& rhs)
126 {
127   assert(lhs.is_a() == rhs.is_a());
128   return !lhs.eq(rhs);
129 }
130 
131 //: Less than operator
132 inline bool operator < (const brdb_value& lhs,
133                         const brdb_value& rhs)
134 {
135   assert(lhs.is_a() == rhs.is_a());
136   return lhs.lt(rhs);
137 }
138 //: Less than operator
139 inline bool operator <= (const brdb_value& lhs,
140                          const brdb_value& rhs)
141 {
142   assert(lhs.is_a() == rhs.is_a());
143   return !rhs.lt(lhs);
144 }
145 
146 //: Greater than operator
147 inline bool operator > (const brdb_value& lhs,
148                         const brdb_value& rhs)
149 {
150   assert(lhs.is_a() == rhs.is_a());
151   return rhs.lt(lhs);
152 }
153 
154 //: Greater than or equal to operator
155 inline bool operator >= (const brdb_value& lhs,
156                          const brdb_value& rhs)
157 {
158   assert(lhs.is_a() == rhs.is_a());
159   return !lhs.lt(rhs);
160 }
161 
162 //: A templated database value class
163 template< class T >
164 class brdb_value_t : public brdb_value
165 {
166  public:
167   //: Default Constructor
168   brdb_value_t<T>() = default;
169 
170   //: Constructor
171   explicit brdb_value_t<T>(T  value)
value_(std::move (value))172    : value_(std::move(value)) {}
173 
174   //: Return the string identifying this class
is_a()175   std::string is_a() const override { return get_type_string(); }
176 
type()177   static std::string const& type() { return get_type_string(); }
178 
179   //: Clone
clone()180   brdb_value * clone() const override { return new brdb_value_t<T>(*this); }
181 
182   //: Test for equality under polymorphism
183   bool eq(const brdb_value& other) const override;
184 
185   //: Test for inequality (less than) under polymorphism
186   bool lt(const brdb_value& other) const override;
187 
188   //: Assign the value of /p other to this if the types are the same
189   bool assign(const brdb_value& other) override;
190 
191   //: Return the string identifying this class
print()192   void print() const override { std::cout << value_ << "   ";}
193 
194   //: Return the value
value()195   T value() const { return value_; }
196 
197   //: Conversion operator
T()198   operator T() const { return value_; }
199 
200   //: Assignment operator
201   brdb_value_t<T>& operator = (const T& rhs) { value_ = rhs; return *this; }
202   //: Assignment operator
203   brdb_value_t<T>& operator = (const brdb_value_t<T>& rhs) { value_ = rhs.value_; return *this; }
204 
205   //---------------------------------------------------------------------------
206   // Binary I/O functions
207 
208   //: binary io read value only
209   //  Handles only the value (without version or type info)
210   void b_read_value(vsl_b_istream& is) override;
211 
212   //: binary io write value only
213   //  Handles only the value (without version or type info)
214   void b_write_value(vsl_b_ostream& os) const override;
215 
216  private:
217   //: The stored data
218   T value_;
219 
220   //: The type identifier string for this class
221   static const std::string& get_type_string();
222 };
223 
224 template< class T >
225 inline bool operator == (const brdb_value_t<T>& lhs,
226                          const brdb_value_t<T>& rhs)
227 {
228   return lhs.value() == rhs.value();
229 }
230 
231 template< class T >
232 inline bool operator == (const T& lhs,
233                          const brdb_value_t<T>& rhs)
234 {
235   return lhs == rhs.value();
236 }
237 
238 template< class T >
239 inline bool operator == (const brdb_value_t<T>& lhs,
240                          const T& rhs)
241 {
242   return lhs.value() == rhs;
243 }
244 
245 template< class T >
246 inline bool operator != (const brdb_value_t<T>& lhs,
247                          const brdb_value_t<T>& rhs)
248 {
249   return lhs.value() != rhs.value();
250 }
251 
252 template< class T >
253 inline bool operator != (const T& lhs,
254                          const brdb_value_t<T>& rhs)
255 {
256   return lhs != rhs.value();
257 }
258 
259 template< class T >
260 inline bool operator != (const brdb_value_t<T>& lhs,
261                          const T& rhs)
262 {
263   return lhs.value() != rhs;
264 }
265 
266 template< class T >
267 inline bool operator <= (const brdb_value_t<T>& lhs,
268                          const brdb_value_t<T>& rhs)
269 {
270   return lhs.value() <= rhs.value();
271 }
272 
273 template< class T >
274 inline bool operator <= (const T& lhs,
275                          const brdb_value_t<T>& rhs)
276 {
277   return lhs <= rhs.value();
278 }
279 
280 template< class T >
281 inline bool operator <= (const brdb_value_t<T>& lhs,
282                          const T& rhs)
283 {
284   return lhs.value() <= rhs;
285 }
286 
287 template< class T >
288 inline bool operator < (const brdb_value_t<T>& lhs,
289                         const brdb_value_t<T>& rhs)
290 {
291   return lhs.value() < rhs.value();
292 }
293 
294 template< class T >
295 inline bool operator < (const T& lhs,
296                         const brdb_value_t<T>& rhs)
297 {
298   return lhs < rhs.value();
299 }
300 
301 template< class T >
302 inline bool operator < (const brdb_value_t<T>& lhs,
303                         const T& rhs)
304 {
305   return lhs.value() < rhs;
306 }
307 
308 template< class T >
309 inline bool operator >= (const brdb_value_t<T>& lhs,
310                          const brdb_value_t<T>& rhs)
311 {
312   return lhs.value() >= rhs.value();
313 }
314 
315 template< class T >
316 inline bool operator >= (const T& lhs,
317                          const brdb_value_t<T>& rhs)
318 {
319   return lhs >= rhs.value();
320 }
321 
322 template< class T >
323 inline bool operator >= (const brdb_value_t<T>& lhs,
324                          const T& rhs)
325 {
326   return lhs.value() >= rhs;
327 }
328 
329 template< class T >
330 inline bool operator > (const brdb_value_t<T>& lhs,
331                         const brdb_value_t<T>& rhs)
332 {
333   return lhs.value() > rhs.value();
334 }
335 
336 template< class T >
337 inline bool operator > (const T& lhs,
338                         const brdb_value_t<T>& rhs)
339 {
340   return lhs > rhs.value();
341 }
342 
343 template< class T >
344 inline bool operator > (const brdb_value_t<T>& lhs,
345                         const T& rhs)
346 {
347   return lhs.value() > rhs;
348 }
349 
350 #endif // brdb_value_h_
351