greg_serialize.hpp 19 KB

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