1 #ifndef GREGORIAN_SERIALIZE_HPP___
2 #define GREGORIAN_SERIALIZE_HPP___
4 /* Copyright (c) 2004-2005 CrystalClear Software, Inc.
5 * Use, modification and distribution is subject to the
6 * Boost Software License, Version 1.0. (See accompanying
7 * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
8 * Author: Jeff Garland, Bart Garst
9 * $Date: 2010-11-11 15:19:38 -0500 (Thu, 11 Nov 2010) $
12 #include "boost/date_time/gregorian/gregorian_types.hpp"
13 #include "boost/date_time/gregorian/parsers.hpp"
14 #include "boost/serialization/split_free.hpp"
15 #include "boost/serialization/nvp.hpp"
18 // macros to split serialize functions into save & load functions
19 // An expanded version is below for gregorian::date
20 // NOTE: these macros define template functions in the boost::serialization namespace.
21 // They must be expanded *outside* of any namespace
22 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration)
23 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration::duration_rep)
24 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_period)
25 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_month)
26 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_day)
27 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_weekday)
28 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::partial_date)
29 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::nth_kday_of_month)
30 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_of_month)
31 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::last_kday_of_month)
32 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_before)
33 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_after)
36 namespace serialization {
38 /*! Method that does serialization for gregorian::date -- splits to load/save
40 template<class Archive>
41 inline void serialize(Archive & ar,
42 ::boost::gregorian::date & d,
43 const unsigned int file_version)
45 split_free(ar, d, file_version);
48 //! Function to save gregorian::date objects using serialization lib
49 /*! Dates are serialized into a string for transport and storage.
50 * While it would be more efficient to store the internal
51 * integer used to manipulate the dates, it is an unstable solution.
53 template<class Archive>
54 void save(Archive & ar,
55 const ::boost::gregorian::date & d,
56 unsigned int /* version */)
58 std::string ds = to_iso_string(d);
59 ar & make_nvp("date", ds);
62 //! Function to load gregorian::date objects using serialization lib
63 /*! Dates are serialized into a string for transport and storage.
64 * While it would be more efficient to store the internal
65 * integer used to manipulate the dates, it is an unstable solution.
67 template<class Archive>
68 void load(Archive & ar,
69 ::boost::gregorian::date & d,
70 unsigned int /*version*/)
73 ar & make_nvp("date", ds);
75 d = ::boost::gregorian::from_undelimited_string(ds);
76 }catch(bad_lexical_cast&) {
77 gregorian::special_values sv = gregorian::special_value_from_string(ds);
78 if(sv == gregorian::not_special) {
79 throw; // no match found, rethrow original exception
82 d = gregorian::date(sv);
88 //!override needed b/c no default constructor
89 template<class Archive>
90 inline void load_construct_data(Archive & ar,
91 ::boost::gregorian::date* dp,
92 const unsigned int /*file_version*/)
94 // retrieve data from archive required to construct new
95 // invoke inplace constructor to initialize instance of date
96 ::new(dp) ::boost::gregorian::date(::boost::gregorian::not_a_date_time);
99 /**** date_duration ****/
101 //! Function to save gregorian::date_duration objects using serialization lib
102 template<class Archive>
103 void save(Archive & ar, const gregorian::date_duration & dd,
104 unsigned int /*version*/)
106 typename gregorian::date_duration::duration_rep dr = dd.get_rep();
107 ar & make_nvp("date_duration", dr);
109 //! Function to load gregorian::date_duration objects using serialization lib
110 template<class Archive>
111 void load(Archive & ar, gregorian::date_duration & dd, unsigned int /*version*/)
113 typename gregorian::date_duration::duration_rep dr(0);
114 ar & make_nvp("date_duration", dr);
115 dd = gregorian::date_duration(dr);
117 //!override needed b/c no default constructor
118 template<class Archive>
119 inline void load_construct_data(Archive & ar, gregorian::date_duration* dd,
120 const unsigned int /*file_version*/)
122 ::new(dd) gregorian::date_duration(gregorian::not_a_date_time);
125 /**** date_duration::duration_rep (most likely int_adapter) ****/
127 //! helper unction to save date_duration objects using serialization lib
128 template<class Archive>
129 void save(Archive & ar, const gregorian::date_duration::duration_rep & dr,
130 unsigned int /*version*/)
132 typename gregorian::date_duration::duration_rep::int_type it = dr.as_number();
133 ar & make_nvp("date_duration_duration_rep", it);
135 //! helper function to load date_duration objects using serialization lib
136 template<class Archive>
137 void load(Archive & ar, gregorian::date_duration::duration_rep & dr, unsigned int /*version*/)
139 typename gregorian::date_duration::duration_rep::int_type it(0);
140 ar & make_nvp("date_duration_duration_rep", it);
141 dr = gregorian::date_duration::duration_rep::int_type(it);
143 //!override needed b/c no default constructor
144 template<class Archive>
145 inline void load_construct_data(Archive & ar, gregorian::date_duration::duration_rep* dr,
146 const unsigned int /*file_version*/)
148 ::new(dr) gregorian::date_duration::duration_rep(0);
151 /**** date_period ****/
153 //! Function to save gregorian::date_period objects using serialization lib
154 /*! date_period objects are broken down into 2 parts for serialization:
155 * the begining date object and the end date object
157 template<class Archive>
158 void save(Archive & ar, const gregorian::date_period& dp,
159 unsigned int /*version*/)
161 gregorian::date d1 = dp.begin();
162 gregorian::date d2 = dp.end();
163 ar & make_nvp("date_period_begin_date", d1);
164 ar & make_nvp("date_period_end_date", d2);
166 //! Function to load gregorian::date_period objects using serialization lib
167 /*! date_period objects are broken down into 2 parts for serialization:
168 * the begining date object and the end date object
170 template<class Archive>
171 void load(Archive & ar, gregorian::date_period& dp, unsigned int /*version*/)
173 gregorian::date d1(gregorian::not_a_date_time);
174 gregorian::date d2(gregorian::not_a_date_time);
175 ar & make_nvp("date_period_begin_date", d1);
176 ar & make_nvp("date_period_end_date", d2);
177 dp = gregorian::date_period(d1,d2);
179 //!override needed b/c no default constructor
180 template<class Archive>
181 inline void load_construct_data(Archive & ar, gregorian::date_period* dp,
182 const unsigned int /*file_version*/)
184 gregorian::date d(gregorian::not_a_date_time);
185 gregorian::date_duration dd(1);
186 ::new(dp) gregorian::date_period(d,dd);
189 /**** greg_month ****/
191 //! Function to save gregorian::greg_month objects using serialization lib
192 template<class Archive>
193 void save(Archive & ar, const gregorian::greg_month& gm,
194 unsigned int /*version*/)
196 unsigned short us = gm.as_number();
197 ar & make_nvp("greg_month", us);
199 //! Function to load gregorian::greg_month objects using serialization lib
200 template<class Archive>
201 void load(Archive & ar, gregorian::greg_month& gm, unsigned int /*version*/)
204 ar & make_nvp("greg_month", us);
205 gm = gregorian::greg_month(us);
207 //!override needed b/c no default constructor
208 template<class Archive>
209 inline void load_construct_data(Archive & ar, gregorian::greg_month* gm,
210 const unsigned int /*file_version*/)
212 ::new(gm) gregorian::greg_month(1);
217 //! Function to save gregorian::greg_day objects using serialization lib
218 template<class Archive>
219 void save(Archive & ar, const gregorian::greg_day& gd,
220 unsigned int /*version*/)
222 unsigned short us = gd.as_number();
223 ar & make_nvp("greg_day", us);
225 //! Function to load gregorian::greg_day objects using serialization lib
226 template<class Archive>
227 void load(Archive & ar, gregorian::greg_day& gd, unsigned int /*version*/)
230 ar & make_nvp("greg_day", us);
231 gd = gregorian::greg_day(us);
233 //!override needed b/c no default constructor
234 template<class Archive>
235 inline void load_construct_data(Archive & ar, gregorian::greg_day* gd,
236 const unsigned int /*file_version*/)
238 ::new(gd) gregorian::greg_day(1);
241 /**** greg_weekday ****/
243 //! Function to save gregorian::greg_weekday objects using serialization lib
244 template<class Archive>
245 void save(Archive & ar, const gregorian::greg_weekday& gd,
246 unsigned int /*version*/)
248 unsigned short us = gd.as_number();
249 ar & make_nvp("greg_weekday", us);
251 //! Function to load gregorian::greg_weekday objects using serialization lib
252 template<class Archive>
253 void load(Archive & ar, gregorian::greg_weekday& gd, unsigned int /*version*/)
256 ar & make_nvp("greg_weekday", us);
257 gd = gregorian::greg_weekday(us);
259 //!override needed b/c no default constructor
260 template<class Archive>
261 inline void load_construct_data(Archive & ar, gregorian::greg_weekday* gd,
262 const unsigned int /*file_version*/)
264 ::new(gd) gregorian::greg_weekday(1);
267 /**** date_generators ****/
269 /**** partial_date ****/
271 //! Function to save gregorian::partial_date objects using serialization lib
272 /*! partial_date objects are broken down into 2 parts for serialization:
273 * the day (typically greg_day) and month (typically greg_month) objects
275 template<class Archive>
276 void save(Archive & ar, const gregorian::partial_date& pd,
277 unsigned int /*version*/)
279 gregorian::greg_day gd(pd.day());
280 gregorian::greg_month gm(pd.month().as_number());
281 ar & make_nvp("partial_date_day", gd);
282 ar & make_nvp("partial_date_month", gm);
284 //! Function to load gregorian::partial_date objects using serialization lib
285 /*! partial_date objects are broken down into 2 parts for serialization:
286 * the day (greg_day) and month (greg_month) objects
288 template<class Archive>
289 void load(Archive & ar, gregorian::partial_date& pd, unsigned int /*version*/)
291 gregorian::greg_day gd(1);
292 gregorian::greg_month gm(1);
293 ar & make_nvp("partial_date_day", gd);
294 ar & make_nvp("partial_date_month", gm);
295 pd = gregorian::partial_date(gd,gm);
297 //!override needed b/c no default constructor
298 template<class Archive>
299 inline void load_construct_data(Archive & ar, gregorian::partial_date* pd,
300 const unsigned int /*file_version*/)
302 gregorian::greg_month gm(1);
303 gregorian::greg_day gd(1);
304 ::new(pd) gregorian::partial_date(gd,gm);
307 /**** nth_kday_of_month ****/
309 //! Function to save nth_day_of_the_week_in_month objects using serialization lib
310 /*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
311 * serialization: the week number, the day of the week, and the month
313 template<class Archive>
314 void save(Archive & ar, const gregorian::nth_kday_of_month& nkd,
315 unsigned int /*version*/)
317 typename gregorian::nth_kday_of_month::week_num wn(nkd.nth_week());
318 typename gregorian::nth_kday_of_month::day_of_week_type d(nkd.day_of_week().as_number());
319 typename gregorian::nth_kday_of_month::month_type m(nkd.month().as_number());
320 ar & make_nvp("nth_kday_of_month_week_num", wn);
321 ar & make_nvp("nth_kday_of_month_day_of_week", d);
322 ar & make_nvp("nth_kday_of_month_month", m);
324 //! Function to load nth_day_of_the_week_in_month objects using serialization lib
325 /*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
326 * serialization: the week number, the day of the week, and the month
328 template<class Archive>
329 void load(Archive & ar, gregorian::nth_kday_of_month& nkd, unsigned int /*version*/)
331 typename gregorian::nth_kday_of_month::week_num wn(gregorian::nth_kday_of_month::first);
332 typename gregorian::nth_kday_of_month::day_of_week_type d(gregorian::Monday);
333 typename gregorian::nth_kday_of_month::month_type m(gregorian::Jan);
334 ar & make_nvp("nth_kday_of_month_week_num", wn);
335 ar & make_nvp("nth_kday_of_month_day_of_week", d);
336 ar & make_nvp("nth_kday_of_month_month", m);
338 nkd = gregorian::nth_kday_of_month(wn,d,m);
340 //!override needed b/c no default constructor
341 template<class Archive>
342 inline void load_construct_data(Archive & ar,
343 gregorian::nth_kday_of_month* nkd,
344 const unsigned int /*file_version*/)
346 // values used are not significant
347 ::new(nkd) gregorian::nth_kday_of_month(gregorian::nth_kday_of_month::first,
348 gregorian::Monday,gregorian::Jan);
351 /**** first_kday_of_month ****/
353 //! Function to save first_day_of_the_week_in_month objects using serialization lib
354 /*! first_day_of_the_week_in_month objects are broken down into 2 parts for
355 * serialization: the day of the week, and the month
357 template<class Archive>
358 void save(Archive & ar, const gregorian::first_kday_of_month& fkd,
359 unsigned int /*version*/)
361 typename gregorian::first_kday_of_month::day_of_week_type d(fkd.day_of_week().as_number());
362 typename gregorian::first_kday_of_month::month_type m(fkd.month().as_number());
363 ar & make_nvp("first_kday_of_month_day_of_week", d);
364 ar & make_nvp("first_kday_of_month_month", m);
366 //! Function to load first_day_of_the_week_in_month objects using serialization lib
367 /*! first_day_of_the_week_in_month objects are broken down into 2 parts for
368 * serialization: the day of the week, and the month
370 template<class Archive>
371 void load(Archive & ar, gregorian::first_kday_of_month& fkd, unsigned int /*version*/)
373 typename gregorian::first_kday_of_month::day_of_week_type d(gregorian::Monday);
374 typename gregorian::first_kday_of_month::month_type m(gregorian::Jan);
375 ar & make_nvp("first_kday_of_month_day_of_week", d);
376 ar & make_nvp("first_kday_of_month_month", m);
378 fkd = gregorian::first_kday_of_month(d,m);
380 //!override needed b/c no default constructor
381 template<class Archive>
382 inline void load_construct_data(Archive & ar,
383 gregorian::first_kday_of_month* fkd,
384 const unsigned int /*file_version*/)
386 // values used are not significant
387 ::new(fkd) gregorian::first_kday_of_month(gregorian::Monday,gregorian::Jan);
390 /**** last_kday_of_month ****/
392 //! Function to save last_day_of_the_week_in_month objects using serialization lib
393 /*! last_day_of_the_week_in_month objects are broken down into 2 parts for
394 * serialization: the day of the week, and the month
396 template<class Archive>
397 void save(Archive & ar, const gregorian::last_kday_of_month& lkd,
398 unsigned int /*version*/)
400 typename gregorian::last_kday_of_month::day_of_week_type d(lkd.day_of_week().as_number());
401 typename gregorian::last_kday_of_month::month_type m(lkd.month().as_number());
402 ar & make_nvp("last_kday_of_month_day_of_week", d);
403 ar & make_nvp("last_kday_of_month_month", m);
405 //! Function to load last_day_of_the_week_in_month objects using serialization lib
406 /*! last_day_of_the_week_in_month objects are broken down into 2 parts for
407 * serialization: the day of the week, and the month
409 template<class Archive>
410 void load(Archive & ar, gregorian::last_kday_of_month& lkd, unsigned int /*version*/)
412 typename gregorian::last_kday_of_month::day_of_week_type d(gregorian::Monday);
413 typename gregorian::last_kday_of_month::month_type m(gregorian::Jan);
414 ar & make_nvp("last_kday_of_month_day_of_week", d);
415 ar & make_nvp("last_kday_of_month_month", m);
417 lkd = gregorian::last_kday_of_month(d,m);
419 //!override needed b/c no default constructor
420 template<class Archive>
421 inline void load_construct_data(Archive & ar,
422 gregorian::last_kday_of_month* lkd,
423 const unsigned int /*file_version*/)
425 // values used are not significant
426 ::new(lkd) gregorian::last_kday_of_month(gregorian::Monday,gregorian::Jan);
429 /**** first_kday_before ****/
431 //! Function to save first_day_of_the_week_before objects using serialization lib
432 template<class Archive>
433 void save(Archive & ar, const gregorian::first_kday_before& fkdb,
434 unsigned int /*version*/)
436 typename gregorian::first_kday_before::day_of_week_type d(fkdb.day_of_week().as_number());
437 ar & make_nvp("first_kday_before_day_of_week", d);
439 //! Function to load first_day_of_the_week_before objects using serialization lib
440 template<class Archive>
441 void load(Archive & ar, gregorian::first_kday_before& fkdb, unsigned int /*version*/)
443 typename gregorian::first_kday_before::day_of_week_type d(gregorian::Monday);
444 ar & make_nvp("first_kday_before_day_of_week", d);
446 fkdb = gregorian::first_kday_before(d);
448 //!override needed b/c no default constructor
449 template<class Archive>
450 inline void load_construct_data(Archive & ar,
451 gregorian::first_kday_before* fkdb,
452 const unsigned int /*file_version*/)
454 // values used are not significant
455 ::new(fkdb) gregorian::first_kday_before(gregorian::Monday);
458 /**** first_kday_after ****/
460 //! Function to save first_day_of_the_week_after objects using serialization lib
461 template<class Archive>
462 void save(Archive & ar, const gregorian::first_kday_after& fkda,
463 unsigned int /*version*/)
465 typename gregorian::first_kday_after::day_of_week_type d(fkda.day_of_week().as_number());
466 ar & make_nvp("first_kday_after_day_of_week", d);
468 //! Function to load first_day_of_the_week_after objects using serialization lib
469 template<class Archive>
470 void load(Archive & ar, gregorian::first_kday_after& fkda, unsigned int /*version*/)
472 typename gregorian::first_kday_after::day_of_week_type d(gregorian::Monday);
473 ar & make_nvp("first_kday_after_day_of_week", d);
475 fkda = gregorian::first_kday_after(d);
477 //!override needed b/c no default constructor
478 template<class Archive>
479 inline void load_construct_data(Archive & ar,
480 gregorian::first_kday_after* fkda,
481 const unsigned int /*file_version*/)
483 // values used are not significant
484 ::new(fkda) gregorian::first_kday_after(gregorian::Monday);
487 } // namespace serialization