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