greg_serialize.hpp 18 KB

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