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
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_year)
26 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_month)
27 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_day)
28 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_weekday)
29 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::partial_date)
30 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::nth_kday_of_month)
31 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_of_month)
32 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::last_kday_of_month)
33 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_before)
34 BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_after)
37 namespace serialization {
39 /*! Method that does serialization for gregorian::date -- splits to load/save
41 template<class Archive>
42 inline void serialize(Archive & ar,
43 ::boost::gregorian::date & d,
44 const unsigned int file_version)
46 split_free(ar, d, file_version);
49 //! Function to save gregorian::date objects using serialization lib
50 /*! Dates are serialized into a string for transport and storage.
51 * While it would be more efficient to store the internal
52 * integer used to manipulate the dates, it is an unstable solution.
54 template<class Archive>
55 void save(Archive & ar,
56 const ::boost::gregorian::date & d,
57 unsigned int /* version */)
59 std::string ds = to_iso_string(d);
60 ar & make_nvp("date", ds);
63 //! Function to load gregorian::date objects using serialization lib
64 /*! Dates are serialized into a string for transport and storage.
65 * While it would be more efficient to store the internal
66 * integer used to manipulate the dates, it is an unstable solution.
68 template<class Archive>
69 void load(Archive & ar,
70 ::boost::gregorian::date & d,
71 unsigned int /*version*/)
74 ar & make_nvp("date", ds);
76 d = ::boost::gregorian::from_undelimited_string(ds);
77 }catch(bad_lexical_cast&) {
78 gregorian::special_values sv = gregorian::special_value_from_string(ds);
79 if(sv == gregorian::not_special) {
80 throw; // no match found, rethrow original exception
83 d = gregorian::date(sv);
89 //!override needed b/c no default constructor
90 template<class Archive>
91 inline void load_construct_data(Archive & /*ar*/,
92 ::boost::gregorian::date* dp,
93 const unsigned int /*file_version*/)
95 // retrieve data from archive required to construct new
96 // invoke inplace constructor to initialize instance of date
97 ::new(dp) ::boost::gregorian::date(::boost::gregorian::not_a_date_time);
100 /**** date_duration ****/
102 //! Function to save gregorian::date_duration objects using serialization lib
103 template<class Archive>
104 void save(Archive & ar, const gregorian::date_duration & dd,
105 unsigned int /*version*/)
107 typename gregorian::date_duration::duration_rep dr = dd.get_rep();
108 ar & make_nvp("date_duration", dr);
110 //! Function to load gregorian::date_duration objects using serialization lib
111 template<class Archive>
112 void load(Archive & ar, gregorian::date_duration & dd, unsigned int /*version*/)
114 typename gregorian::date_duration::duration_rep dr(0);
115 ar & make_nvp("date_duration", dr);
116 dd = gregorian::date_duration(dr);
118 //!override needed b/c no default constructor
119 template<class Archive>
120 inline void load_construct_data(Archive & /*ar*/, gregorian::date_duration* dd,
121 const unsigned int /*file_version*/)
123 ::new(dd) gregorian::date_duration(gregorian::not_a_date_time);
126 /**** date_duration::duration_rep (most likely int_adapter) ****/
128 //! helper unction to save date_duration objects using serialization lib
129 template<class Archive>
130 void save(Archive & ar, const gregorian::date_duration::duration_rep & dr,
131 unsigned int /*version*/)
133 typename gregorian::date_duration::duration_rep::int_type it = dr.as_number();
134 ar & make_nvp("date_duration_duration_rep", it);
136 //! helper function to load date_duration objects using serialization lib
137 template<class Archive>
138 void load(Archive & ar, gregorian::date_duration::duration_rep & dr, unsigned int /*version*/)
140 typename gregorian::date_duration::duration_rep::int_type it(0);
141 ar & make_nvp("date_duration_duration_rep", it);
142 dr = gregorian::date_duration::duration_rep::int_type(it);
144 //!override needed b/c no default constructor
145 template<class Archive>
146 inline void load_construct_data(Archive & /*ar*/, gregorian::date_duration::duration_rep* dr,
147 const unsigned int /*file_version*/)
149 ::new(dr) gregorian::date_duration::duration_rep(0);
152 /**** date_period ****/
154 //! Function to save gregorian::date_period objects using serialization lib
155 /*! date_period objects are broken down into 2 parts for serialization:
156 * the begining date object and the end date object
158 template<class Archive>
159 void save(Archive & ar, const gregorian::date_period& dp,
160 unsigned int /*version*/)
162 gregorian::date d1 = dp.begin();
163 gregorian::date d2 = dp.end();
164 ar & make_nvp("date_period_begin_date", d1);
165 ar & make_nvp("date_period_end_date", d2);
167 //! Function to load gregorian::date_period objects using serialization lib
168 /*! date_period objects are broken down into 2 parts for serialization:
169 * the begining date object and the end date object
171 template<class Archive>
172 void load(Archive & ar, gregorian::date_period& dp, unsigned int /*version*/)
174 gregorian::date d1(gregorian::not_a_date_time);
175 gregorian::date d2(gregorian::not_a_date_time);
176 ar & make_nvp("date_period_begin_date", d1);
177 ar & make_nvp("date_period_end_date", d2);
178 dp = gregorian::date_period(d1,d2);
180 //!override needed b/c no default constructor
181 template<class Archive>
182 inline void load_construct_data(Archive & /*ar*/, gregorian::date_period* dp,
183 const unsigned int /*file_version*/)
185 gregorian::date d(gregorian::not_a_date_time);
186 gregorian::date_duration dd(1);
187 ::new(dp) gregorian::date_period(d,dd);
190 /**** greg_year ****/
192 //! Function to save gregorian::greg_year objects using serialization lib
193 template<class Archive>
194 void save(Archive & ar, const gregorian::greg_year& gy,
195 unsigned int /*version*/)
197 unsigned short us = gy;
198 ar & make_nvp("greg_year", us);
200 //! Function to load gregorian::greg_year objects using serialization lib
201 template<class Archive>
202 void load(Archive & ar, gregorian::greg_year& gy, unsigned int /*version*/)
205 ar & make_nvp("greg_year", us);
206 gy = gregorian::greg_year(us);
208 //!override needed b/c no default constructor
209 template<class Archive>
210 inline void load_construct_data(Archive & /*ar*/, gregorian::greg_year* gy,
211 const unsigned int /*file_version*/)
213 ::new(gy) gregorian::greg_year(1900);
216 /**** greg_month ****/
218 //! Function to save gregorian::greg_month objects using serialization lib
219 template<class Archive>
220 void save(Archive & ar, const gregorian::greg_month& gm,
221 unsigned int /*version*/)
223 unsigned short us = gm.as_number();
224 ar & make_nvp("greg_month", us);
226 //! Function to load gregorian::greg_month objects using serialization lib
227 template<class Archive>
228 void load(Archive & ar, gregorian::greg_month& gm, unsigned int /*version*/)
231 ar & make_nvp("greg_month", us);
232 gm = gregorian::greg_month(us);
234 //!override needed b/c no default constructor
235 template<class Archive>
236 inline void load_construct_data(Archive & /*ar*/, gregorian::greg_month* gm,
237 const unsigned int /*file_version*/)
239 ::new(gm) gregorian::greg_month(1);
244 //! Function to save gregorian::greg_day objects using serialization lib
245 template<class Archive>
246 void save(Archive & ar, const gregorian::greg_day& gd,
247 unsigned int /*version*/)
249 unsigned short us = gd.as_number();
250 ar & make_nvp("greg_day", us);
252 //! Function to load gregorian::greg_day objects using serialization lib
253 template<class Archive>
254 void load(Archive & ar, gregorian::greg_day& gd, unsigned int /*version*/)
257 ar & make_nvp("greg_day", us);
258 gd = gregorian::greg_day(us);
260 //!override needed b/c no default constructor
261 template<class Archive>
262 inline void load_construct_data(Archive & /*ar*/, gregorian::greg_day* gd,
263 const unsigned int /*file_version*/)
265 ::new(gd) gregorian::greg_day(1);
268 /**** greg_weekday ****/
270 //! Function to save gregorian::greg_weekday objects using serialization lib
271 template<class Archive>
272 void save(Archive & ar, const gregorian::greg_weekday& gd,
273 unsigned int /*version*/)
275 unsigned short us = gd.as_number();
276 ar & make_nvp("greg_weekday", us);
278 //! Function to load gregorian::greg_weekday objects using serialization lib
279 template<class Archive>
280 void load(Archive & ar, gregorian::greg_weekday& gd, unsigned int /*version*/)
283 ar & make_nvp("greg_weekday", us);
284 gd = gregorian::greg_weekday(us);
286 //!override needed b/c no default constructor
287 template<class Archive>
288 inline void load_construct_data(Archive & /*ar*/, gregorian::greg_weekday* gd,
289 const unsigned int /*file_version*/)
291 ::new(gd) gregorian::greg_weekday(1);
294 /**** date_generators ****/
296 /**** partial_date ****/
298 //! Function to save gregorian::partial_date objects using serialization lib
299 /*! partial_date objects are broken down into 2 parts for serialization:
300 * the day (typically greg_day) and month (typically greg_month) objects
302 template<class Archive>
303 void save(Archive & ar, const gregorian::partial_date& pd,
304 unsigned int /*version*/)
306 gregorian::greg_day gd(pd.day());
307 gregorian::greg_month gm(pd.month().as_number());
308 ar & make_nvp("partial_date_day", gd);
309 ar & make_nvp("partial_date_month", gm);
311 //! Function to load gregorian::partial_date objects using serialization lib
312 /*! partial_date objects are broken down into 2 parts for serialization:
313 * the day (greg_day) and month (greg_month) objects
315 template<class Archive>
316 void load(Archive & ar, gregorian::partial_date& pd, unsigned int /*version*/)
318 gregorian::greg_day gd(1);
319 gregorian::greg_month gm(1);
320 ar & make_nvp("partial_date_day", gd);
321 ar & make_nvp("partial_date_month", gm);
322 pd = gregorian::partial_date(gd,gm);
324 //!override needed b/c no default constructor
325 template<class Archive>
326 inline void load_construct_data(Archive & /*ar*/, gregorian::partial_date* pd,
327 const unsigned int /*file_version*/)
329 gregorian::greg_month gm(1);
330 gregorian::greg_day gd(1);
331 ::new(pd) gregorian::partial_date(gd,gm);
334 /**** nth_kday_of_month ****/
336 //! Function to save nth_day_of_the_week_in_month objects using serialization lib
337 /*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
338 * serialization: the week number, the day of the week, and the month
340 template<class Archive>
341 void save(Archive & ar, const gregorian::nth_kday_of_month& nkd,
342 unsigned int /*version*/)
344 typename gregorian::nth_kday_of_month::week_num wn(nkd.nth_week());
345 typename gregorian::nth_kday_of_month::day_of_week_type d(nkd.day_of_week().as_number());
346 typename gregorian::nth_kday_of_month::month_type m(nkd.month().as_number());
347 ar & make_nvp("nth_kday_of_month_week_num", wn);
348 ar & make_nvp("nth_kday_of_month_day_of_week", d);
349 ar & make_nvp("nth_kday_of_month_month", m);
351 //! Function to load nth_day_of_the_week_in_month objects using serialization lib
352 /*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
353 * serialization: the week number, the day of the week, and the month
355 template<class Archive>
356 void load(Archive & ar, gregorian::nth_kday_of_month& nkd, unsigned int /*version*/)
358 typename gregorian::nth_kday_of_month::week_num wn(gregorian::nth_kday_of_month::first);
359 typename gregorian::nth_kday_of_month::day_of_week_type d(gregorian::Monday);
360 typename gregorian::nth_kday_of_month::month_type m(gregorian::Jan);
361 ar & make_nvp("nth_kday_of_month_week_num", wn);
362 ar & make_nvp("nth_kday_of_month_day_of_week", d);
363 ar & make_nvp("nth_kday_of_month_month", m);
365 nkd = gregorian::nth_kday_of_month(wn,d,m);
367 //!override needed b/c no default constructor
368 template<class Archive>
369 inline void load_construct_data(Archive & /*ar*/,
370 gregorian::nth_kday_of_month* nkd,
371 const unsigned int /*file_version*/)
373 // values used are not significant
374 ::new(nkd) gregorian::nth_kday_of_month(gregorian::nth_kday_of_month::first,
375 gregorian::Monday,gregorian::Jan);
378 /**** first_kday_of_month ****/
380 //! Function to save first_day_of_the_week_in_month objects using serialization lib
381 /*! first_day_of_the_week_in_month objects are broken down into 2 parts for
382 * serialization: the day of the week, and the month
384 template<class Archive>
385 void save(Archive & ar, const gregorian::first_kday_of_month& fkd,
386 unsigned int /*version*/)
388 typename gregorian::first_kday_of_month::day_of_week_type d(fkd.day_of_week().as_number());
389 typename gregorian::first_kday_of_month::month_type m(fkd.month().as_number());
390 ar & make_nvp("first_kday_of_month_day_of_week", d);
391 ar & make_nvp("first_kday_of_month_month", m);
393 //! Function to load first_day_of_the_week_in_month objects using serialization lib
394 /*! first_day_of_the_week_in_month objects are broken down into 2 parts for
395 * serialization: the day of the week, and the month
397 template<class Archive>
398 void load(Archive & ar, gregorian::first_kday_of_month& fkd, unsigned int /*version*/)
400 typename gregorian::first_kday_of_month::day_of_week_type d(gregorian::Monday);
401 typename gregorian::first_kday_of_month::month_type m(gregorian::Jan);
402 ar & make_nvp("first_kday_of_month_day_of_week", d);
403 ar & make_nvp("first_kday_of_month_month", m);
405 fkd = gregorian::first_kday_of_month(d,m);
407 //!override needed b/c no default constructor
408 template<class Archive>
409 inline void load_construct_data(Archive & /*ar*/,
410 gregorian::first_kday_of_month* fkd,
411 const unsigned int /*file_version*/)
413 // values used are not significant
414 ::new(fkd) gregorian::first_kday_of_month(gregorian::Monday,gregorian::Jan);
417 /**** last_kday_of_month ****/
419 //! Function to save last_day_of_the_week_in_month objects using serialization lib
420 /*! last_day_of_the_week_in_month objects are broken down into 2 parts for
421 * serialization: the day of the week, and the month
423 template<class Archive>
424 void save(Archive & ar, const gregorian::last_kday_of_month& lkd,
425 unsigned int /*version*/)
427 typename gregorian::last_kday_of_month::day_of_week_type d(lkd.day_of_week().as_number());
428 typename gregorian::last_kday_of_month::month_type m(lkd.month().as_number());
429 ar & make_nvp("last_kday_of_month_day_of_week", d);
430 ar & make_nvp("last_kday_of_month_month", m);
432 //! Function to load last_day_of_the_week_in_month objects using serialization lib
433 /*! last_day_of_the_week_in_month objects are broken down into 2 parts for
434 * serialization: the day of the week, and the month
436 template<class Archive>
437 void load(Archive & ar, gregorian::last_kday_of_month& lkd, unsigned int /*version*/)
439 typename gregorian::last_kday_of_month::day_of_week_type d(gregorian::Monday);
440 typename gregorian::last_kday_of_month::month_type m(gregorian::Jan);
441 ar & make_nvp("last_kday_of_month_day_of_week", d);
442 ar & make_nvp("last_kday_of_month_month", m);
444 lkd = gregorian::last_kday_of_month(d,m);
446 //!override needed b/c no default constructor
447 template<class Archive>
448 inline void load_construct_data(Archive & /*ar*/,
449 gregorian::last_kday_of_month* lkd,
450 const unsigned int /*file_version*/)
452 // values used are not significant
453 ::new(lkd) gregorian::last_kday_of_month(gregorian::Monday,gregorian::Jan);
456 /**** first_kday_before ****/
458 //! Function to save first_day_of_the_week_before objects using serialization lib
459 template<class Archive>
460 void save(Archive & ar, const gregorian::first_kday_before& fkdb,
461 unsigned int /*version*/)
463 typename gregorian::first_kday_before::day_of_week_type d(fkdb.day_of_week().as_number());
464 ar & make_nvp("first_kday_before_day_of_week", d);
466 //! Function to load first_day_of_the_week_before objects using serialization lib
467 template<class Archive>
468 void load(Archive & ar, gregorian::first_kday_before& fkdb, unsigned int /*version*/)
470 typename gregorian::first_kday_before::day_of_week_type d(gregorian::Monday);
471 ar & make_nvp("first_kday_before_day_of_week", d);
473 fkdb = gregorian::first_kday_before(d);
475 //!override needed b/c no default constructor
476 template<class Archive>
477 inline void load_construct_data(Archive & /*ar*/,
478 gregorian::first_kday_before* fkdb,
479 const unsigned int /*file_version*/)
481 // values used are not significant
482 ::new(fkdb) gregorian::first_kday_before(gregorian::Monday);
485 /**** first_kday_after ****/
487 //! Function to save first_day_of_the_week_after objects using serialization lib
488 template<class Archive>
489 void save(Archive & ar, const gregorian::first_kday_after& fkda,
490 unsigned int /*version*/)
492 typename gregorian::first_kday_after::day_of_week_type d(fkda.day_of_week().as_number());
493 ar & make_nvp("first_kday_after_day_of_week", d);
495 //! Function to load first_day_of_the_week_after objects using serialization lib
496 template<class Archive>
497 void load(Archive & ar, gregorian::first_kday_after& fkda, unsigned int /*version*/)
499 typename gregorian::first_kday_after::day_of_week_type d(gregorian::Monday);
500 ar & make_nvp("first_kday_after_day_of_week", d);
502 fkda = gregorian::first_kday_after(d);
504 //!override needed b/c no default constructor
505 template<class Archive>
506 inline void load_construct_data(Archive & /*ar*/,
507 gregorian::first_kday_after* fkda,
508 const unsigned int /*file_version*/)
510 // values used are not significant
511 ::new(fkda) gregorian::first_kday_after(gregorian::Monday);
514 } // namespace serialization