greg_serialize.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. #ifndef GREGORIAN_SERIALIZE_HPP___
  2. #define GREGORIAN_SERIALIZE_HPP___
  3. /* Copyright (c) 2004-2005 CrystalClear Software, Inc.
  4. * Use, modification and distribution is subject to the
  5. * Boost Software License, Version 1.0. (See accompanying
  6. * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  7. * Author: Jeff Garland, Bart Garst
  8. * $Date$
  9. */
  10. #include "boost/date_time/gregorian/gregorian_types.hpp"
  11. #include "boost/date_time/gregorian/parsers.hpp"
  12. #include "boost/serialization/split_free.hpp"
  13. #include "boost/serialization/nvp.hpp"
  14. // macros to split serialize functions into save & load functions
  15. // An expanded version is below for gregorian::date
  16. // NOTE: these macros define template functions in the boost::serialization namespace.
  17. // They must be expanded *outside* of any namespace
  18. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration)
  19. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration::duration_rep)
  20. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_period)
  21. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_year)
  22. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_month)
  23. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_day)
  24. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_weekday)
  25. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::partial_date)
  26. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::nth_kday_of_month)
  27. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_of_month)
  28. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::last_kday_of_month)
  29. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_before)
  30. BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_after)
  31. namespace boost {
  32. namespace gregorian {
  33. std::string to_iso_string(const date&);
  34. }
  35. namespace serialization {
  36. /*! Method that does serialization for gregorian::date -- splits to load/save
  37. */
  38. template<class Archive>
  39. inline void serialize(Archive & ar,
  40. ::boost::gregorian::date & d,
  41. const unsigned int file_version)
  42. {
  43. split_free(ar, d, file_version);
  44. }
  45. //! Function to save gregorian::date objects using serialization lib
  46. /*! Dates are serialized into a string for transport and storage.
  47. * While it would be more efficient to store the internal
  48. * integer used to manipulate the dates, it is an unstable solution.
  49. */
  50. template<class Archive>
  51. void save(Archive & ar,
  52. const ::boost::gregorian::date & d,
  53. unsigned int /* version */)
  54. {
  55. std::string ds = to_iso_string(d);
  56. ar & make_nvp("date", ds);
  57. }
  58. //! Function to load gregorian::date objects using serialization lib
  59. /*! Dates are serialized into a string for transport and storage.
  60. * While it would be more efficient to store the internal
  61. * integer used to manipulate the dates, it is an unstable solution.
  62. */
  63. template<class Archive>
  64. void load(Archive & ar,
  65. ::boost::gregorian::date & d,
  66. unsigned int /*version*/)
  67. {
  68. std::string ds;
  69. ar & make_nvp("date", ds);
  70. try{
  71. d = ::boost::gregorian::from_undelimited_string(ds);
  72. }catch(bad_lexical_cast&) {
  73. gregorian::special_values sv = gregorian::special_value_from_string(ds);
  74. if(sv == gregorian::not_special) {
  75. throw; // no match found, rethrow original exception
  76. }
  77. else {
  78. d = gregorian::date(sv);
  79. }
  80. }
  81. }
  82. //!override needed b/c no default constructor
  83. template<class Archive>
  84. inline void load_construct_data(Archive & /*ar*/,
  85. ::boost::gregorian::date* dp,
  86. const unsigned int /*file_version*/)
  87. {
  88. // retrieve data from archive required to construct new
  89. // invoke inplace constructor to initialize instance of date
  90. ::new(dp) ::boost::gregorian::date(::boost::gregorian::not_a_date_time);
  91. }
  92. /**** date_duration ****/
  93. //! Function to save gregorian::date_duration objects using serialization lib
  94. template<class Archive>
  95. void save(Archive & ar, const gregorian::date_duration & dd,
  96. unsigned int /*version*/)
  97. {
  98. typename gregorian::date_duration::duration_rep dr = dd.get_rep();
  99. ar & make_nvp("date_duration", dr);
  100. }
  101. //! Function to load gregorian::date_duration objects using serialization lib
  102. template<class Archive>
  103. void load(Archive & ar, gregorian::date_duration & dd, unsigned int /*version*/)
  104. {
  105. typename gregorian::date_duration::duration_rep dr(0);
  106. ar & make_nvp("date_duration", dr);
  107. dd = gregorian::date_duration(dr);
  108. }
  109. //!override needed b/c no default constructor
  110. template<class Archive>
  111. inline void load_construct_data(Archive & /*ar*/, gregorian::date_duration* dd,
  112. const unsigned int /*file_version*/)
  113. {
  114. ::new(dd) gregorian::date_duration(gregorian::not_a_date_time);
  115. }
  116. /**** date_duration::duration_rep (most likely int_adapter) ****/
  117. //! helper unction to save date_duration objects using serialization lib
  118. template<class Archive>
  119. void save(Archive & ar, const gregorian::date_duration::duration_rep & dr,
  120. unsigned int /*version*/)
  121. {
  122. typename gregorian::date_duration::duration_rep::int_type it = dr.as_number();
  123. ar & make_nvp("date_duration_duration_rep", it);
  124. }
  125. //! helper function to load date_duration objects using serialization lib
  126. template<class Archive>
  127. void load(Archive & ar, gregorian::date_duration::duration_rep & dr, unsigned int /*version*/)
  128. {
  129. typename gregorian::date_duration::duration_rep::int_type it(0);
  130. ar & make_nvp("date_duration_duration_rep", it);
  131. dr = gregorian::date_duration::duration_rep::int_type(it);
  132. }
  133. //!override needed b/c no default constructor
  134. template<class Archive>
  135. inline void load_construct_data(Archive & /*ar*/, gregorian::date_duration::duration_rep* dr,
  136. const unsigned int /*file_version*/)
  137. {
  138. ::new(dr) gregorian::date_duration::duration_rep(0);
  139. }
  140. /**** date_period ****/
  141. //! Function to save gregorian::date_period objects using serialization lib
  142. /*! date_period objects are broken down into 2 parts for serialization:
  143. * the begining date object and the end date object
  144. */
  145. template<class Archive>
  146. void save(Archive & ar, const gregorian::date_period& dp,
  147. unsigned int /*version*/)
  148. {
  149. gregorian::date d1 = dp.begin();
  150. gregorian::date d2 = dp.end();
  151. ar & make_nvp("date_period_begin_date", d1);
  152. ar & make_nvp("date_period_end_date", d2);
  153. }
  154. //! Function to load 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
  157. */
  158. template<class Archive>
  159. void load(Archive & ar, gregorian::date_period& dp, unsigned int /*version*/)
  160. {
  161. gregorian::date d1(gregorian::not_a_date_time);
  162. gregorian::date d2(gregorian::not_a_date_time);
  163. ar & make_nvp("date_period_begin_date", d1);
  164. ar & make_nvp("date_period_end_date", d2);
  165. dp = gregorian::date_period(d1,d2);
  166. }
  167. //!override needed b/c no default constructor
  168. template<class Archive>
  169. inline void load_construct_data(Archive & /*ar*/, gregorian::date_period* dp,
  170. const unsigned int /*file_version*/)
  171. {
  172. gregorian::date d(gregorian::not_a_date_time);
  173. gregorian::date_duration dd(1);
  174. ::new(dp) gregorian::date_period(d,dd);
  175. }
  176. /**** greg_year ****/
  177. //! Function to save gregorian::greg_year objects using serialization lib
  178. template<class Archive>
  179. void save(Archive & ar, const gregorian::greg_year& gy,
  180. unsigned int /*version*/)
  181. {
  182. unsigned short us = gy;
  183. ar & make_nvp("greg_year", us);
  184. }
  185. //! Function to load gregorian::greg_year objects using serialization lib
  186. template<class Archive>
  187. void load(Archive & ar, gregorian::greg_year& gy, unsigned int /*version*/)
  188. {
  189. unsigned short us;
  190. ar & make_nvp("greg_year", us);
  191. gy = gregorian::greg_year(us);
  192. }
  193. //!override needed b/c no default constructor
  194. template<class Archive>
  195. inline void load_construct_data(Archive & /*ar*/, gregorian::greg_year* gy,
  196. const unsigned int /*file_version*/)
  197. {
  198. ::new(gy) gregorian::greg_year(1900);
  199. }
  200. /**** greg_month ****/
  201. //! Function to save gregorian::greg_month objects using serialization lib
  202. template<class Archive>
  203. void save(Archive & ar, const gregorian::greg_month& gm,
  204. unsigned int /*version*/)
  205. {
  206. unsigned short us = gm.as_number();
  207. ar & make_nvp("greg_month", us);
  208. }
  209. //! Function to load gregorian::greg_month objects using serialization lib
  210. template<class Archive>
  211. void load(Archive & ar, gregorian::greg_month& gm, unsigned int /*version*/)
  212. {
  213. unsigned short us;
  214. ar & make_nvp("greg_month", us);
  215. gm = gregorian::greg_month(us);
  216. }
  217. //!override needed b/c no default constructor
  218. template<class Archive>
  219. inline void load_construct_data(Archive & /*ar*/, gregorian::greg_month* gm,
  220. const unsigned int /*file_version*/)
  221. {
  222. ::new(gm) gregorian::greg_month(1);
  223. }
  224. /**** greg_day ****/
  225. //! Function to save gregorian::greg_day objects using serialization lib
  226. template<class Archive>
  227. void save(Archive & ar, const gregorian::greg_day& gd,
  228. unsigned int /*version*/)
  229. {
  230. unsigned short us = gd.as_number();
  231. ar & make_nvp("greg_day", us);
  232. }
  233. //! Function to load gregorian::greg_day objects using serialization lib
  234. template<class Archive>
  235. void load(Archive & ar, gregorian::greg_day& gd, unsigned int /*version*/)
  236. {
  237. unsigned short us;
  238. ar & make_nvp("greg_day", us);
  239. gd = gregorian::greg_day(us);
  240. }
  241. //!override needed b/c no default constructor
  242. template<class Archive>
  243. inline void load_construct_data(Archive & /*ar*/, gregorian::greg_day* gd,
  244. const unsigned int /*file_version*/)
  245. {
  246. ::new(gd) gregorian::greg_day(1);
  247. }
  248. /**** greg_weekday ****/
  249. //! Function to save gregorian::greg_weekday objects using serialization lib
  250. template<class Archive>
  251. void save(Archive & ar, const gregorian::greg_weekday& gd,
  252. unsigned int /*version*/)
  253. {
  254. unsigned short us = gd.as_number();
  255. ar & make_nvp("greg_weekday", us);
  256. }
  257. //! Function to load gregorian::greg_weekday objects using serialization lib
  258. template<class Archive>
  259. void load(Archive & ar, gregorian::greg_weekday& gd, unsigned int /*version*/)
  260. {
  261. unsigned short us;
  262. ar & make_nvp("greg_weekday", us);
  263. gd = gregorian::greg_weekday(us);
  264. }
  265. //!override needed b/c no default constructor
  266. template<class Archive>
  267. inline void load_construct_data(Archive & /*ar*/, gregorian::greg_weekday* gd,
  268. const unsigned int /*file_version*/)
  269. {
  270. ::new(gd) gregorian::greg_weekday(1);
  271. }
  272. /**** date_generators ****/
  273. /**** partial_date ****/
  274. //! Function to save gregorian::partial_date objects using serialization lib
  275. /*! partial_date objects are broken down into 2 parts for serialization:
  276. * the day (typically greg_day) and month (typically greg_month) objects
  277. */
  278. template<class Archive>
  279. void save(Archive & ar, const gregorian::partial_date& pd,
  280. unsigned int /*version*/)
  281. {
  282. gregorian::greg_day gd(pd.day());
  283. gregorian::greg_month gm(pd.month().as_number());
  284. ar & make_nvp("partial_date_day", gd);
  285. ar & make_nvp("partial_date_month", gm);
  286. }
  287. //! Function to load gregorian::partial_date objects using serialization lib
  288. /*! partial_date objects are broken down into 2 parts for serialization:
  289. * the day (greg_day) and month (greg_month) objects
  290. */
  291. template<class Archive>
  292. void load(Archive & ar, gregorian::partial_date& pd, unsigned int /*version*/)
  293. {
  294. gregorian::greg_day gd(1);
  295. gregorian::greg_month gm(1);
  296. ar & make_nvp("partial_date_day", gd);
  297. ar & make_nvp("partial_date_month", gm);
  298. pd = gregorian::partial_date(gd,gm);
  299. }
  300. //!override needed b/c no default constructor
  301. template<class Archive>
  302. inline void load_construct_data(Archive & /*ar*/, gregorian::partial_date* pd,
  303. const unsigned int /*file_version*/)
  304. {
  305. gregorian::greg_month gm(1);
  306. gregorian::greg_day gd(1);
  307. ::new(pd) gregorian::partial_date(gd,gm);
  308. }
  309. /**** nth_kday_of_month ****/
  310. //! Function to save nth_day_of_the_week_in_month objects using serialization lib
  311. /*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
  312. * serialization: the week number, the day of the week, and the month
  313. */
  314. template<class Archive>
  315. void save(Archive & ar, const gregorian::nth_kday_of_month& nkd,
  316. unsigned int /*version*/)
  317. {
  318. typename gregorian::nth_kday_of_month::week_num wn(nkd.nth_week());
  319. typename gregorian::nth_kday_of_month::day_of_week_type d(nkd.day_of_week().as_number());
  320. typename gregorian::nth_kday_of_month::month_type m(nkd.month().as_number());
  321. ar & make_nvp("nth_kday_of_month_week_num", wn);
  322. ar & make_nvp("nth_kday_of_month_day_of_week", d);
  323. ar & make_nvp("nth_kday_of_month_month", m);
  324. }
  325. //! Function to load nth_day_of_the_week_in_month objects using serialization lib
  326. /*! nth_day_of_the_week_in_month objects are broken down into 3 parts for
  327. * serialization: the week number, the day of the week, and the month
  328. */
  329. template<class Archive>
  330. void load(Archive & ar, gregorian::nth_kday_of_month& nkd, unsigned int /*version*/)
  331. {
  332. typename gregorian::nth_kday_of_month::week_num wn(gregorian::nth_kday_of_month::first);
  333. typename gregorian::nth_kday_of_month::day_of_week_type d(gregorian::Monday);
  334. typename gregorian::nth_kday_of_month::month_type m(gregorian::Jan);
  335. ar & make_nvp("nth_kday_of_month_week_num", wn);
  336. ar & make_nvp("nth_kday_of_month_day_of_week", d);
  337. ar & make_nvp("nth_kday_of_month_month", m);
  338. nkd = gregorian::nth_kday_of_month(wn,d,m);
  339. }
  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*/)
  345. {
  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);
  349. }
  350. /**** first_kday_of_month ****/
  351. //! Function to save first_day_of_the_week_in_month objects using serialization lib
  352. /*! first_day_of_the_week_in_month objects are broken down into 2 parts for
  353. * serialization: the day of the week, and the month
  354. */
  355. template<class Archive>
  356. void save(Archive & ar, const gregorian::first_kday_of_month& fkd,
  357. unsigned int /*version*/)
  358. {
  359. typename gregorian::first_kday_of_month::day_of_week_type d(fkd.day_of_week().as_number());
  360. typename gregorian::first_kday_of_month::month_type m(fkd.month().as_number());
  361. ar & make_nvp("first_kday_of_month_day_of_week", d);
  362. ar & make_nvp("first_kday_of_month_month", m);
  363. }
  364. //! Function to load first_day_of_the_week_in_month objects using serialization lib
  365. /*! first_day_of_the_week_in_month objects are broken down into 2 parts for
  366. * serialization: the day of the week, and the month
  367. */
  368. template<class Archive>
  369. void load(Archive & ar, gregorian::first_kday_of_month& fkd, unsigned int /*version*/)
  370. {
  371. typename gregorian::first_kday_of_month::day_of_week_type d(gregorian::Monday);
  372. typename gregorian::first_kday_of_month::month_type m(gregorian::Jan);
  373. ar & make_nvp("first_kday_of_month_day_of_week", d);
  374. ar & make_nvp("first_kday_of_month_month", m);
  375. fkd = gregorian::first_kday_of_month(d,m);
  376. }
  377. //!override needed b/c no default constructor
  378. template<class Archive>
  379. inline void load_construct_data(Archive & /*ar*/,
  380. gregorian::first_kday_of_month* fkd,
  381. const unsigned int /*file_version*/)
  382. {
  383. // values used are not significant
  384. ::new(fkd) gregorian::first_kday_of_month(gregorian::Monday,gregorian::Jan);
  385. }
  386. /**** last_kday_of_month ****/
  387. //! Function to save last_day_of_the_week_in_month objects using serialization lib
  388. /*! last_day_of_the_week_in_month objects are broken down into 2 parts for
  389. * serialization: the day of the week, and the month
  390. */
  391. template<class Archive>
  392. void save(Archive & ar, const gregorian::last_kday_of_month& lkd,
  393. unsigned int /*version*/)
  394. {
  395. typename gregorian::last_kday_of_month::day_of_week_type d(lkd.day_of_week().as_number());
  396. typename gregorian::last_kday_of_month::month_type m(lkd.month().as_number());
  397. ar & make_nvp("last_kday_of_month_day_of_week", d);
  398. ar & make_nvp("last_kday_of_month_month", m);
  399. }
  400. //! Function to load last_day_of_the_week_in_month objects using serialization lib
  401. /*! last_day_of_the_week_in_month objects are broken down into 2 parts for
  402. * serialization: the day of the week, and the month
  403. */
  404. template<class Archive>
  405. void load(Archive & ar, gregorian::last_kday_of_month& lkd, unsigned int /*version*/)
  406. {
  407. typename gregorian::last_kday_of_month::day_of_week_type d(gregorian::Monday);
  408. typename gregorian::last_kday_of_month::month_type m(gregorian::Jan);
  409. ar & make_nvp("last_kday_of_month_day_of_week", d);
  410. ar & make_nvp("last_kday_of_month_month", m);
  411. lkd = gregorian::last_kday_of_month(d,m);
  412. }
  413. //!override needed b/c no default constructor
  414. template<class Archive>
  415. inline void load_construct_data(Archive & /*ar*/,
  416. gregorian::last_kday_of_month* lkd,
  417. const unsigned int /*file_version*/)
  418. {
  419. // values used are not significant
  420. ::new(lkd) gregorian::last_kday_of_month(gregorian::Monday,gregorian::Jan);
  421. }
  422. /**** first_kday_before ****/
  423. //! Function to save first_day_of_the_week_before objects using serialization lib
  424. template<class Archive>
  425. void save(Archive & ar, const gregorian::first_kday_before& fkdb,
  426. unsigned int /*version*/)
  427. {
  428. typename gregorian::first_kday_before::day_of_week_type d(fkdb.day_of_week().as_number());
  429. ar & make_nvp("first_kday_before_day_of_week", d);
  430. }
  431. //! Function to load first_day_of_the_week_before objects using serialization lib
  432. template<class Archive>
  433. void load(Archive & ar, gregorian::first_kday_before& fkdb, unsigned int /*version*/)
  434. {
  435. typename gregorian::first_kday_before::day_of_week_type d(gregorian::Monday);
  436. ar & make_nvp("first_kday_before_day_of_week", d);
  437. fkdb = gregorian::first_kday_before(d);
  438. }
  439. //!override needed b/c no default constructor
  440. template<class Archive>
  441. inline void load_construct_data(Archive & /*ar*/,
  442. gregorian::first_kday_before* fkdb,
  443. const unsigned int /*file_version*/)
  444. {
  445. // values used are not significant
  446. ::new(fkdb) gregorian::first_kday_before(gregorian::Monday);
  447. }
  448. /**** first_kday_after ****/
  449. //! Function to save first_day_of_the_week_after objects using serialization lib
  450. template<class Archive>
  451. void save(Archive & ar, const gregorian::first_kday_after& fkda,
  452. unsigned int /*version*/)
  453. {
  454. typename gregorian::first_kday_after::day_of_week_type d(fkda.day_of_week().as_number());
  455. ar & make_nvp("first_kday_after_day_of_week", d);
  456. }
  457. //! Function to load first_day_of_the_week_after objects using serialization lib
  458. template<class Archive>
  459. void load(Archive & ar, gregorian::first_kday_after& fkda, unsigned int /*version*/)
  460. {
  461. typename gregorian::first_kday_after::day_of_week_type d(gregorian::Monday);
  462. ar & make_nvp("first_kday_after_day_of_week", d);
  463. fkda = gregorian::first_kday_after(d);
  464. }
  465. //!override needed b/c no default constructor
  466. template<class Archive>
  467. inline void load_construct_data(Archive & /*ar*/,
  468. gregorian::first_kday_after* fkda,
  469. const unsigned int /*file_version*/)
  470. {
  471. // values used are not significant
  472. ::new(fkda) gregorian::first_kday_after(gregorian::Monday);
  473. }
  474. } // namespace serialization
  475. } // namespace boost
  476. #endif