中间件底层,websocket

variant.hpp 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. //******************************************************************************
  2. // RCF - Remote Call Framework
  3. //
  4. // Copyright (c) 2005 - 2020, Delta V Software. All rights reserved.
  5. // http://www.deltavsoft.com
  6. //
  7. // RCF is distributed under dual licenses - closed source or GPL.
  8. // Consult your particular license for conditions of use.
  9. //
  10. // If you have not purchased a commercial license, you are using RCF
  11. // under GPL terms.
  12. //
  13. // Version: 3.2
  14. // Contact: support <at> deltavsoft.com
  15. //
  16. //******************************************************************************
  17. #ifndef INCLUDE_SF_VARIANT_HPP
  18. #define INCLUDE_SF_VARIANT_HPP
  19. #include <boost/variant.hpp>
  20. #include <boost/mpl/front.hpp>
  21. #include <boost/mpl/pop_front.hpp>
  22. #include <boost/mpl/eval_if.hpp>
  23. #include <boost/mpl/identity.hpp>
  24. #include <boost/mpl/size.hpp>
  25. #include <boost/mpl/empty.hpp>
  26. namespace SF {
  27. class Archive;
  28. class VariantSerializer : public boost::static_visitor<>
  29. {
  30. public:
  31. VariantSerializer(SF::Archive &ar) : mAr(ar)
  32. {}
  33. template<typename T>
  34. void operator()(const T &t) const
  35. {
  36. mAr & t;
  37. }
  38. private:
  39. SF::Archive &mAr;
  40. };
  41. template<class S>
  42. struct VariantDeserializer
  43. {
  44. struct LoadNull
  45. {
  46. template<class V>
  47. static void invoke(
  48. SF::Archive &,
  49. int,
  50. V &)
  51. {}
  52. };
  53. struct Load
  54. {
  55. template<class V>
  56. static void invoke(
  57. SF::Archive & ar,
  58. int which,
  59. V & v)
  60. {
  61. using namespace boost::mpl;
  62. if (which == 0)
  63. {
  64. typedef BOOST_DEDUCED_TYPENAME front<S>::type head_type;
  65. head_type value;
  66. ar & value;
  67. v = value;
  68. }
  69. else
  70. {
  71. typedef BOOST_DEDUCED_TYPENAME pop_front<S>::type type;
  72. VariantDeserializer<type>::load(ar, which - 1, v);
  73. }
  74. }
  75. };
  76. template<class V>
  77. static void load(
  78. SF::Archive & ar,
  79. int which,
  80. V & v)
  81. {
  82. using namespace boost::mpl;
  83. typedef BOOST_DEDUCED_TYPENAME eval_if<empty<S>,
  84. boost::mpl::identity<LoadNull>,
  85. boost::mpl::identity<Load>
  86. >::type typex;
  87. typex::invoke(ar, which, v);
  88. }
  89. };
  90. template< BOOST_VARIANT_ENUM_PARAMS(class T) >
  91. void serialize_vc6(
  92. SF::Archive & ar,
  93. boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) > & v,
  94. const unsigned int)
  95. {
  96. if (ar.isWrite())
  97. {
  98. ar & int(v.which());
  99. VariantSerializer variantSerializer(ar);
  100. v.apply_visitor(variantSerializer);
  101. }
  102. else
  103. {
  104. int which = 0;
  105. ar & which;
  106. typedef BOOST_DEDUCED_TYPENAME
  107. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types types;
  108. if(which >= boost::mpl::size<types>::value)
  109. {
  110. RCF::Exception e(
  111. RCF::RcfError_VariantDeserialization,
  112. which,
  113. boost::mpl::size<types>::value);
  114. RCF_THROW(e);
  115. }
  116. VariantDeserializer<types>::load(ar, which, v);
  117. }
  118. }
  119. } // namespace SF
  120. #endif // ! INCLUDE_SF_VARIANT_HPP