Variant.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *
00003  * Copyright (C) 2009-2010 Cassio Neri Moreira
00004  *
00005  * This file is part of the KeyValue library.
00006  *
00007  * The KeyValue library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License as published
00009  * by the Free Software Foundation, either version 3 of the License, or (at
00010  * your option) any later version.
00011  *
00012  * The KeyValue library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
00015  * Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License along
00018  * with KeyValue. If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  * If you modify this library, or any covered work, by linking or combining
00021  * it with Excel (or a modified version of that program), containing parts
00022  * covered by the terms of End-User License Agreement for Microsoft
00023  * Software, the licensors of KeyValue grant you additional permission to
00024  * convey the resulting work.
00025  *
00026  **************************************************************************/
00027 
00034 #ifndef KEYVALUE_VALUE_VARIANT_H_
00035 #define KEYVALUE_VALUE_VARIANT_H_
00036 
00037 #include <iosfwd>
00038 
00039 #include <boost/variant.hpp>
00040 
00041 #include "keyvalue/extern/String.h"
00042 #include "keyvalue/extern/Ptime.h"
00043 #include "keyvalue/frontend/LexicalToolKit.h"
00044 #include "keyvalue/value/Nothing.h"
00045 
00046 namespace keyvalue {
00047 namespace value {
00048 
00049 // Forward declaration
00050 class Single;
00051 
00065 class Variant {
00066 
00067 public:
00068 
00069   typedef boost::variant<Nothing, bool, double, ptime, string> DataType_;
00070 
00074   Variant();
00075 
00083   Variant(const DataType_& data);
00084 
00092   template <typename Rhs>
00093   Variant(const Rhs& rhs);
00094 
00102   Variant(const Single& data);
00103 
00113   template <typename Rhs>
00114   Variant&
00115   operator=(const Rhs& rhs);
00116 
00124   Variant&
00125   operator=(const Single& rhs);
00126 
00157   template <typename ElementType>
00158   bool
00159   is(frontend::LexicalToolKit::IO io) const;
00160 
00195   template <typename ElementType>
00196   ElementType
00197   get(frontend::LexicalToolKit::IO io) const;
00198 
00199   friend std::ostream&
00200   operator<<(std::ostream& os, const Variant& variant);
00201 
00202 private:
00203 
00215   template <typename ElementType>
00216   const ElementType*
00217   get() const;
00218 
00219   DataType_ data_;
00220 
00221 }; // class Variant
00222 
00228 std::ostream&
00229 operator<<(std::ostream& os, const Variant& rhs);
00230 
00254 template <typename Rhs>
00255 struct Parent;
00256 
00257 template <>
00258 struct Parent<Variant::DataType_> {
00259   typedef Variant Type_;
00260 };
00261 
00262 template <>
00263 struct Parent<Nothing> {
00264   typedef Variant::DataType_ Type_;
00265 };
00266 
00267 template <>
00268 struct Parent<bool> {
00269   typedef Variant::DataType_ Type_;
00270 };
00271 
00272 template <>
00273 struct Parent<double> {
00274   typedef Variant::DataType_ Type_;
00275 };
00276 
00277 template <>
00278 struct Parent<int> {
00279   typedef double Type_;
00280 };
00281 
00282 template <>
00283 struct Parent<unsigned int> {
00284   typedef double Type_;
00285 };
00286 
00287 template <>
00288 struct Parent<long unsigned int> {
00289   typedef double Type_;
00290 };
00291 
00292 template <>
00293 struct Parent<string> {
00294   typedef Variant::DataType_ Type_;
00295 };
00296 
00297 template <>
00298 struct Parent<char[]> {
00299   typedef string Type_;
00300 };
00301 
00302 template <size_t N>
00303 struct Parent<char[N]> {
00304   typedef string Type_;
00305 };
00306 
00307 template <>
00308 struct Parent<char *> {
00309   typedef string Type_;
00310 };
00311 
00312 template <>
00313 struct Parent<const char[]> {
00314   typedef string Type_;
00315 };
00316 
00317 template <size_t N>
00318 struct Parent<const char[N]> {
00319   typedef string Type_;
00320 };
00321 
00322 template <>
00323 struct Parent<const char *> {
00324   typedef string Type_;
00325 };
00326 
00327 template <>
00328 struct Parent<ptime> {
00329   typedef Variant::DataType_ Type_;
00330 };
00331 
00332 /*--------------------------------------------------------------------------
00333  * Variant()
00334  *------------------------------------------------------------------------*/
00335 
00336 template <typename Rhs>
00337 Variant::Variant(const Rhs& rhs) :
00338   data_(Variant(typename Parent<Rhs>::Type_(rhs)).data_) {
00343 }
00344 
00345 /*--------------------------------------------------------------------------
00346  * operator=()
00347  *------------------------------------------------------------------------*/
00348 
00349 template <typename Rhs>
00350 Variant&
00351 Variant::operator=(const Rhs& rhs) {
00356   return *this = typename Parent<Rhs>::Type_(rhs);
00357 }
00358 
00359 } // namespace value
00360 } // namespace keyvalue
00361 
00362 #endif // KEYVALUE_VALUE_VARIANT_H_