std_interoperability.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Support for interoperability between Boost.System and <system_error>
  2. //
  3. // Copyright 2018 Peter Dimov
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // See library home page at http://www.boost.org/libs/system
  9. #include <system_error>
  10. #include <map>
  11. #include <memory>
  12. //
  13. namespace boost
  14. {
  15. namespace system
  16. {
  17. namespace detail
  18. {
  19. class BOOST_SYMBOL_VISIBLE std_category: public std::error_category
  20. {
  21. private:
  22. boost::system::error_category const * pc_;
  23. public:
  24. explicit std_category( boost::system::error_category const * pc ): pc_( pc )
  25. {
  26. }
  27. virtual const char * name() const BOOST_NOEXCEPT
  28. {
  29. return pc_->name();
  30. }
  31. virtual std::string message( int ev ) const
  32. {
  33. return pc_->message( ev );
  34. }
  35. virtual std::error_condition default_error_condition( int ev ) const BOOST_NOEXCEPT
  36. {
  37. return pc_->default_error_condition( ev );
  38. }
  39. virtual bool equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT;
  40. virtual bool equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT;
  41. };
  42. inline std::error_category const & to_std_category( boost::system::error_category const & cat )
  43. {
  44. typedef std::map< boost::system::error_category const *, std::unique_ptr<std_category> > map_type;
  45. static map_type map_;
  46. map_type::iterator i = map_.find( &cat );
  47. if( i == map_.end() )
  48. {
  49. std::unique_ptr<std_category> p( new std_category( &cat ) );
  50. std::pair<map_type::iterator, bool> r = map_.insert( map_type::value_type( &cat, std::move( p ) ) );
  51. i = r.first;
  52. }
  53. return *i->second;
  54. }
  55. inline bool std_category::equivalent( int code, const std::error_condition & condition ) const BOOST_NOEXCEPT
  56. {
  57. if( condition.category() == *this )
  58. {
  59. boost::system::error_condition bn( condition.value(), *pc_ );
  60. return pc_->equivalent( code, bn );
  61. }
  62. else if( condition.category() == std::generic_category() || condition.category() == boost::system::generic_category() )
  63. {
  64. boost::system::error_condition bn( condition.value(), boost::system::generic_category() );
  65. return pc_->equivalent( code, bn );
  66. }
  67. #ifndef BOOST_NO_RTTI
  68. else if( std_category const* pc2 = dynamic_cast< std_category const* >( &condition.category() ) )
  69. {
  70. boost::system::error_condition bn( condition.value(), *pc2->pc_ );
  71. return pc_->equivalent( code, bn );
  72. }
  73. #endif
  74. else
  75. {
  76. return default_error_condition( code ) == condition;
  77. }
  78. }
  79. inline bool std_category::equivalent( const std::error_code & code, int condition ) const BOOST_NOEXCEPT
  80. {
  81. if( code.category() == *this )
  82. {
  83. boost::system::error_code bc( code.value(), *pc_ );
  84. return pc_->equivalent( bc, condition );
  85. }
  86. else if( code.category() == std::generic_category() || code.category() == boost::system::generic_category() )
  87. {
  88. boost::system::error_code bc( code.value(), boost::system::generic_category() );
  89. return pc_->equivalent( bc, condition );
  90. }
  91. #ifndef BOOST_NO_RTTI
  92. else if( std_category const* pc2 = dynamic_cast< std_category const* >( &code.category() ) )
  93. {
  94. boost::system::error_code bc( code.value(), *pc2->pc_ );
  95. return pc_->equivalent( bc, condition );
  96. }
  97. #endif
  98. else if( *pc_ == boost::system::generic_category() )
  99. {
  100. return std::generic_category().equivalent( code, condition );
  101. }
  102. else
  103. {
  104. return false;
  105. }
  106. }
  107. } // namespace detail
  108. } // namespace system
  109. } // namespace boost