greg_serialize.hpp 19 KB

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