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 #include <xlnt/utils/datetime.hpp>
25 #include <xlnt/utils/variant.hpp>
26 
27 namespace xlnt {
28 
variant()29 variant::variant()
30     : type_(type::null)
31 {
32 }
33 
variant(const std::string & value)34 variant::variant(const std::string &value)
35     : type_(type::lpstr),
36       lpstr_value_(value)
37 {
38 }
39 
variant(const char * value)40 variant::variant(const char *value)
41     : variant(std::string(value))
42 {
43 }
44 
variant(int32_t value)45 variant::variant(int32_t value)
46     : type_(type::i4),
47       i4_value_(value)
48 {
49 }
50 
variant(bool value)51 variant::variant(bool value)
52     : type_(type::boolean),
53       i4_value_(value ? 1 : 0)
54 {
55 }
56 
variant(const datetime & value)57 variant::variant(const datetime &value)
58     : type_(type::date),
59       lpstr_value_(value.to_iso_string())
60 {
61 }
62 
variant(const std::initializer_list<int> & value)63 variant::variant(const std::initializer_list<int> &value)
64     : type_(type::vector)
65 {
66     for (const auto &v : value)
67     {
68         vector_value_.emplace_back(v);
69     }
70 }
71 
variant(const std::vector<int> & value)72 variant::variant(const std::vector<int> &value)
73     : type_(type::vector)
74 {
75     for (const auto &v : value)
76     {
77         vector_value_.emplace_back(v);
78     }
79 }
80 
variant(const std::initializer_list<const char * > & value)81 variant::variant(const std::initializer_list<const char *> &value)
82     : type_(type::vector)
83 {
84     for (const auto &v : value)
85     {
86         vector_value_.emplace_back(v);
87     }
88 }
89 
variant(const std::vector<const char * > & value)90 variant::variant(const std::vector<const char *> &value)
91     : type_(type::vector)
92 {
93     for (const auto &v : value)
94     {
95         vector_value_.emplace_back(v);
96     }
97 }
98 
variant(const std::initializer_list<std::string> & value)99 variant::variant(const std::initializer_list<std::string> &value)
100     : type_(type::vector)
101 {
102     for (const auto &v : value)
103     {
104         vector_value_.emplace_back(v);
105     }
106 }
107 
variant(const std::vector<std::string> & value)108 variant::variant(const std::vector<std::string> &value)
109     : type_(type::vector)
110 {
111     for (const auto &v : value)
112     {
113         vector_value_.emplace_back(v);
114     }
115 }
116 
variant(const std::vector<variant> & value)117 variant::variant(const std::vector<variant> &value)
118     : type_(type::vector)
119 {
120     for (const auto &v : value)
121     {
122         vector_value_.emplace_back(v);
123     }
124 }
125 
operator ==(const variant & rhs) const126 bool variant::operator==(const variant &rhs) const
127 {
128     if (type_ != rhs.type_)
129     {
130         return false;
131     }
132     switch (type_)
133     {
134     case type::vector:
135         return vector_value_ == rhs.vector_value_;
136     case type::i4:
137     case type::boolean:
138         return i4_value_ == rhs.i4_value_;
139     case type::date:
140     case type::lpstr:
141         return lpstr_value_ == rhs.lpstr_value_;
142     case type::null:
143         return true;
144     }
145     return false;
146 }
147 
is(type t) const148 bool variant::is(type t) const
149 {
150     return type_ == t;
151 }
152 
153 template <>
get() const154 XLNT_API std::string variant::get() const
155 {
156     return lpstr_value_;
157 }
158 
159 template <>
get() const160 XLNT_API std::vector<variant> variant::get() const
161 {
162     return vector_value_;
163 }
164 
165 template <>
get() const166 XLNT_API bool variant::get() const
167 {
168     return i4_value_ != 0;
169 }
170 
171 template <>
get() const172 XLNT_API std::int32_t variant::get() const
173 {
174     return i4_value_;
175 }
176 
177 template <>
get() const178 XLNT_API datetime variant::get() const
179 {
180     return datetime::from_iso_string(lpstr_value_);
181 }
182 
value_type() const183 variant::type variant::value_type() const
184 {
185     return type_;
186 }
187 
188 } // namespace xlnt
189