1 // Copyright (c) 2017-2020 Thomas Fussell 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE 20 // 21 // @license: http://www.opensource.org/licenses/mit-license.php 22 // @author: see AUTHORS file 23 24 #pragma once 25 26 #include <string> 27 #include <vector> 28 29 #include <xlnt/xlnt_config.hpp> 30 31 namespace xlnt { 32 33 struct datetime; 34 35 /// <summary> 36 /// Represents an object that can have variable type. 37 /// </summary> 38 class XLNT_API variant 39 { 40 public: 41 // TODO: implement remaining types? 42 43 /// <summary> 44 /// The possible types a variant can hold. 45 /// </summary> 46 enum class type 47 { 48 vector, 49 //array, 50 //blob, 51 //oblob, 52 //empty, 53 null, 54 //i1, 55 //i2, 56 i4, 57 //i8, 58 //integer, 59 //ui1, 60 //ui2, 61 //ui4, 62 //ui8, 63 //uint, 64 //r4, 65 //r8, 66 //decimal, 67 lpstr, // TODO: how does this differ from lpwstr? 68 //lpwstr, 69 //bstr, 70 date, 71 //filetime, 72 boolean, 73 //cy, 74 //error, 75 //stream, 76 //ostream, 77 //storage, 78 //ostorage, 79 //vstream, 80 //clsid 81 }; 82 83 /// <summary> 84 /// Default constructor. Creates a null-type variant. 85 /// </summary> 86 variant(); 87 88 /// <summary> 89 /// Creates a string-type variant with the given value. 90 /// </summary> 91 variant(const std::string &value); 92 93 /// <summary> 94 /// Creates a string-type variant with the given value. 95 /// </summary> 96 variant(const char *value); 97 98 /// <summary> 99 /// Creates a i4-type variant with the given value. 100 /// </summary> 101 variant(std::int32_t value); 102 103 /// <summary> 104 /// Creates a bool-type variant with the given value. 105 /// </summary> 106 variant(bool value); 107 108 /// <summary> 109 /// Creates a date-type variant with the given value. 110 /// </summary> 111 variant(const datetime &value); 112 113 /// <summary> 114 /// Creates a vector_i4-type variant with the given value. 115 /// </summary> 116 variant(const std::initializer_list<std::int32_t> &value); 117 118 /// <summary> 119 /// Creates a vector_i4-type variant with the given value. 120 /// </summary> 121 variant(const std::vector<std::int32_t> &value); 122 123 /// <summary> 124 /// Creates a vector_string-type variant with the given value. 125 /// </summary> 126 variant(const std::initializer_list<const char *> &value); 127 128 /// <summary> 129 /// Creates a vector_string-type variant with the given value. 130 /// </summary> 131 variant(const std::vector<const char *> &value); 132 133 /// <summary> 134 /// Creates a vector_string-type variant with the given value. 135 /// </summary> 136 variant(const std::initializer_list<std::string> &value); 137 138 /// <summary> 139 /// Creates a vector_string-type variant with the given value. 140 /// </summary> 141 variant(const std::vector<std::string> &value); 142 143 /// <summary> 144 /// Creates a vector_variant-type variant with the given value. 145 /// </summary> 146 variant(const std::vector<variant> &value); 147 148 /// <summary> 149 /// Returns true if this variant is of type t. 150 /// </summary> 151 bool is(type t) const; 152 153 /// <summary> 154 /// Returns the value of this variant as type T. An exception will 155 /// be thrown if the types are not convertible. 156 /// </summary> 157 template <typename T> 158 T get() const; 159 160 /// <summary> 161 /// Returns the type of this variant. 162 /// </summary> 163 type value_type() const; 164 165 bool operator==(const variant &rhs) const; 166 167 private: 168 type type_; 169 std::vector<variant> vector_value_; 170 std::int32_t i4_value_; 171 std::string lpstr_value_; 172 }; 173 174 template <> 175 bool variant::get() const; 176 177 template <> 178 std::int32_t variant::get() const; 179 180 template <> 181 std::string variant::get() const; 182 183 template <> 184 datetime variant::get() const; 185 186 template <> 187 std::vector<std::int32_t> variant::get() const; 188 189 template <> 190 std::vector<std::string> variant::get() const; 191 192 template <> 193 std::vector<variant> variant::get() const; 194 195 } // namespace xlnt 196