Warning, file /include/boost/system/detail/error_code.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #ifndef BOOST_SYSTEM_DETAIL_ERROR_CODE_HPP_INCLUDED
0002 #define BOOST_SYSTEM_DETAIL_ERROR_CODE_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <boost/system/is_error_code_enum.hpp>
0014 #include <boost/system/detail/error_category.hpp>
0015 #include <boost/system/detail/error_condition.hpp>
0016 #include <boost/system/detail/system_category.hpp>
0017 #include <boost/system/detail/system_category_impl.hpp>
0018 #include <boost/system/detail/interop_category.hpp>
0019 #include <boost/system/detail/enable_if.hpp>
0020 #include <boost/system/detail/is_same.hpp>
0021 #include <boost/system/detail/append_int.hpp>
0022 #include <boost/system/detail/snprintf.hpp>
0023 #include <boost/system/detail/config.hpp>
0024 #include <boost/system/detail/std_category.hpp>
0025 #include <boost/assert/source_location.hpp>
0026 #include <boost/cstdint.hpp>
0027 #include <boost/config.hpp>
0028 #include <boost/config/workaround.hpp>
0029 #include <ostream>
0030 #include <new>
0031 #include <cstdio>
0032 #include <system_error>
0033
0034 #if defined(BOOST_GCC) && BOOST_GCC >= 40600 && BOOST_GCC < 70000
0035 # pragma GCC diagnostic push
0036 # pragma GCC diagnostic ignored "-Wstrict-aliasing"
0037 #endif
0038
0039 namespace boost
0040 {
0041
0042 namespace system
0043 {
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 bool operator==( const error_code & code, const error_condition & condition ) noexcept;
0055 std::size_t hash_value( error_code const & ec );
0056
0057 class error_code
0058 {
0059 private:
0060
0061 friend bool operator==( const error_code & code, const error_condition & condition ) noexcept;
0062 friend std::size_t hash_value( error_code const & ec );
0063
0064 private:
0065
0066 struct data
0067 {
0068 int val_;
0069 const error_category * cat_;
0070 };
0071
0072 union
0073 {
0074 data d1_;
0075 unsigned char d2_[ sizeof(std::error_code) ];
0076 };
0077
0078
0079
0080
0081
0082
0083 boost::uintptr_t lc_flags_;
0084
0085 private:
0086
0087 char const* category_name() const noexcept
0088 {
0089
0090
0091 if( lc_flags_ == 0 )
0092 {
0093
0094 return "system";
0095 }
0096 else if( lc_flags_ == 1 )
0097 {
0098
0099 return "std:unknown";
0100 }
0101 else
0102 {
0103 return d1_.cat_->name();
0104 }
0105 }
0106
0107 public:
0108
0109
0110
0111 constexpr error_code() noexcept:
0112 d1_(), lc_flags_( 0 )
0113 {
0114 }
0115
0116 BOOST_SYSTEM_CONSTEXPR error_code( int val, const error_category & cat ) noexcept:
0117 d1_(), lc_flags_( 2 + detail::failed_impl( val, cat ) )
0118 {
0119 d1_.val_ = val;
0120 d1_.cat_ = &cat;
0121 }
0122
0123 error_code( int val, const error_category & cat, source_location const * loc ) noexcept:
0124 d1_(), lc_flags_( ( loc? reinterpret_cast<boost::uintptr_t>( loc ): 2 ) | +detail::failed_impl( val, cat ) )
0125 {
0126 d1_.val_ = val;
0127 d1_.cat_ = &cat;
0128 }
0129
0130 template<class ErrorCodeEnum> BOOST_SYSTEM_CONSTEXPR error_code( ErrorCodeEnum e,
0131 typename detail::enable_if<
0132 is_error_code_enum<ErrorCodeEnum>::value
0133 || std::is_error_code_enum<ErrorCodeEnum>::value
0134 >::type* = 0 ) noexcept: d1_(), lc_flags_( 0 )
0135 {
0136 *this = make_error_code( e );
0137 }
0138
0139 error_code( error_code const& ec, source_location const * loc ) noexcept:
0140 d1_(), lc_flags_( 0 )
0141 {
0142 *this = ec;
0143
0144 if( ec.lc_flags_ != 0 && ec.lc_flags_ != 1 )
0145 {
0146 lc_flags_ = ( loc? reinterpret_cast<boost::uintptr_t>( loc ): 2 ) | ( ec.lc_flags_ & 1 );
0147 }
0148 }
0149
0150 error_code( std::error_code const& ec ) noexcept:
0151 d1_(), lc_flags_( 0 )
0152 {
0153 #ifndef BOOST_NO_RTTI
0154
0155 if( detail::std_category const* pc2 = dynamic_cast< detail::std_category const* >( &ec.category() ) )
0156 {
0157 *this = boost::system::error_code( ec.value(), pc2->original_category() );
0158 }
0159 else
0160
0161 #endif
0162 {
0163 ::new( d2_ ) std::error_code( ec );
0164 lc_flags_ = 1;
0165 }
0166 }
0167
0168
0169
0170 BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) noexcept
0171 {
0172 *this = error_code( val, cat );
0173 }
0174
0175 void assign( int val, const error_category & cat, source_location const * loc ) noexcept
0176 {
0177 *this = error_code( val, cat, loc );
0178 }
0179
0180 void assign( error_code const& ec, source_location const * loc ) noexcept
0181 {
0182 *this = error_code( ec, loc );
0183 }
0184
0185 template<typename ErrorCodeEnum>
0186 BOOST_SYSTEM_CONSTEXPR typename detail::enable_if<is_error_code_enum<ErrorCodeEnum>::value, error_code>::type &
0187 operator=( ErrorCodeEnum val ) noexcept
0188 {
0189 *this = make_error_code( val );
0190 return *this;
0191 }
0192
0193 BOOST_SYSTEM_CONSTEXPR void clear() noexcept
0194 {
0195 *this = error_code();
0196 }
0197
0198
0199
0200 BOOST_SYSTEM_CONSTEXPR int value() const noexcept
0201 {
0202 if( lc_flags_ != 1 )
0203 {
0204 return d1_.val_;
0205 }
0206 else
0207 {
0208 std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
0209
0210 unsigned cv = static_cast<unsigned>( ec.value() );
0211 unsigned ch = static_cast<unsigned>( reinterpret_cast<boost::uintptr_t>( &ec.category() ) % 2097143 );
0212
0213 return static_cast<int>( cv + 1000 * ch );
0214 }
0215 }
0216
0217 BOOST_SYSTEM_CONSTEXPR const error_category & category() const noexcept
0218 {
0219 if( lc_flags_ == 0 )
0220 {
0221 return system_category();
0222 }
0223 else if( lc_flags_ == 1 )
0224 {
0225 return detail::interop_category();
0226 }
0227 else
0228 {
0229 return *d1_.cat_;
0230 }
0231 }
0232
0233
0234 error_condition default_error_condition() const noexcept
0235 {
0236 return category().default_error_condition( value() );
0237 }
0238
0239 std::string message() const
0240 {
0241 if( lc_flags_ == 1 )
0242 {
0243 std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
0244 return ec.message();
0245 }
0246 else if( lc_flags_ == 0 )
0247 {
0248 return detail::system_error_category_message( value() );
0249 }
0250 else
0251 {
0252 return category().message( value() );
0253 }
0254 }
0255
0256 char const * message( char * buffer, std::size_t len ) const noexcept
0257 {
0258 if( lc_flags_ == 1 )
0259 {
0260 std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
0261
0262 #if !defined(BOOST_NO_EXCEPTIONS)
0263 try
0264 #endif
0265 {
0266 detail::snprintf( buffer, len, "%s", ec.message().c_str() );
0267 return buffer;
0268 }
0269 #if !defined(BOOST_NO_EXCEPTIONS)
0270 catch( ... )
0271 {
0272 detail::snprintf( buffer, len, "No message text available for error std:%s:%d", ec.category().name(), ec.value() );
0273 return buffer;
0274 }
0275 #endif
0276 }
0277 else if( lc_flags_ == 0 )
0278 {
0279 return detail::system_error_category_message( value(), buffer, len );
0280 }
0281 else
0282 {
0283 return category().message( value(), buffer, len );
0284 }
0285 }
0286
0287 BOOST_SYSTEM_CONSTEXPR bool failed() const noexcept
0288 {
0289 if( lc_flags_ & 1 )
0290 {
0291 if( lc_flags_ == 1 )
0292 {
0293 std::error_code const& ec = *reinterpret_cast<std::error_code const*>( d2_ );
0294 return ec.value() != 0;
0295 }
0296
0297 return true;
0298 }
0299 else
0300 {
0301 return false;
0302 }
0303 }
0304
0305 BOOST_SYSTEM_CONSTEXPR explicit operator bool() const noexcept
0306 {
0307 return failed();
0308 }
0309
0310 bool has_location() const noexcept
0311 {
0312 return lc_flags_ >= 4;
0313 }
0314
0315 source_location const & location() const noexcept
0316 {
0317 BOOST_STATIC_CONSTEXPR source_location loc;
0318 return lc_flags_ >= 4? *reinterpret_cast<source_location const*>( lc_flags_ &~ static_cast<boost::uintptr_t>( 1 ) ): loc;
0319 }
0320
0321
0322
0323 private:
0324
0325
0326
0327 friend class error_category;
0328
0329 BOOST_SYSTEM_CONSTEXPR bool equals( int val, error_category const& cat ) const noexcept
0330 {
0331 if( lc_flags_ == 0 )
0332 {
0333 return val == 0 && cat.id_ == detail::system_category_id;
0334 }
0335 else if( lc_flags_ == 1 )
0336 {
0337 return cat.id_ == detail::interop_category_id && val == value();
0338 }
0339 else
0340 {
0341 return val == d1_.val_ && cat == *d1_.cat_;
0342 }
0343 }
0344
0345 public:
0346
0347
0348
0349
0350 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_code & lhs, const error_code & rhs ) noexcept
0351 {
0352 bool s1 = lhs.lc_flags_ == 1;
0353 bool s2 = rhs.lc_flags_ == 1;
0354
0355 if( s1 != s2 ) return false;
0356
0357 if( s1 && s2 )
0358 {
0359 std::error_code const& e1 = *reinterpret_cast<std::error_code const*>( lhs.d2_ );
0360 std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( rhs.d2_ );
0361
0362 return e1 == e2;
0363 }
0364 else
0365 {
0366 return lhs.value() == rhs.value() && lhs.category() == rhs.category();
0367 }
0368 }
0369
0370 BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_code & lhs, const error_code & rhs ) noexcept
0371 {
0372 bool s1 = lhs.lc_flags_ == 1;
0373 bool s2 = rhs.lc_flags_ == 1;
0374
0375 if( s1 < s2 ) return true;
0376 if( s2 < s1 ) return false;
0377
0378 if( s1 && s2 )
0379 {
0380 std::error_code const& e1 = *reinterpret_cast<std::error_code const*>( lhs.d2_ );
0381 std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( rhs.d2_ );
0382
0383 return e1 < e2;
0384 }
0385 else
0386 {
0387 return lhs.category() < rhs.category() || (lhs.category() == rhs.category() && lhs.value() < rhs.value());
0388 }
0389 }
0390
0391 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_code & lhs, const error_code & rhs ) noexcept
0392 {
0393 return !( lhs == rhs );
0394 }
0395
0396 inline friend bool operator==( std::error_code const & lhs, error_code const & rhs ) noexcept
0397 {
0398 return lhs == static_cast< std::error_code >( rhs );
0399 }
0400
0401 inline friend bool operator==( error_code const & lhs, std::error_code const & rhs ) noexcept
0402 {
0403 return static_cast< std::error_code >( lhs ) == rhs;
0404 }
0405
0406 inline friend bool operator!=( std::error_code const & lhs, error_code const & rhs ) noexcept
0407 {
0408 return !( lhs == rhs );
0409 }
0410
0411 inline friend bool operator!=( error_code const & lhs, std::error_code const & rhs ) noexcept
0412 {
0413 return !( lhs == rhs );
0414 }
0415
0416
0417
0418 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0419 inline friend bool operator==( error_code const & lhs, E rhs ) noexcept
0420 {
0421 return lhs == make_error_condition( rhs );
0422 }
0423
0424 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0425 inline friend bool operator==( E lhs, error_code const & rhs ) noexcept
0426 {
0427 return make_error_condition( lhs ) == rhs;
0428 }
0429
0430 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0431 inline friend bool operator!=( error_code const & lhs, E rhs ) noexcept
0432 {
0433 return !( lhs == rhs );
0434 }
0435
0436 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0437 inline friend bool operator!=( E lhs, error_code const & rhs ) noexcept
0438 {
0439 return !( lhs == rhs );
0440 }
0441
0442
0443
0444 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0445 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( error_code const & lhs, E rhs ) noexcept
0446 {
0447 return lhs == make_error_code( rhs );
0448 }
0449
0450 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0451 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( E lhs, error_code const & rhs ) noexcept
0452 {
0453 return make_error_code( lhs ) == rhs;
0454 }
0455
0456 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0457 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( error_code const & lhs, E rhs ) noexcept
0458 {
0459 return !( lhs == rhs );
0460 }
0461
0462 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0463 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( E lhs, error_code const & rhs ) noexcept
0464 {
0465 return !( lhs == rhs );
0466 }
0467
0468 #if defined(BOOST_SYSTEM_CLANG_6)
0469
0470 inline friend bool operator==( error_code const & lhs, std::error_condition const & rhs ) noexcept
0471 {
0472 return static_cast< std::error_code >( lhs ) == rhs;
0473 }
0474
0475 inline friend bool operator==( std::error_condition const & lhs, error_code const & rhs ) noexcept
0476 {
0477 return lhs == static_cast< std::error_code >( rhs );
0478 }
0479
0480 inline friend bool operator!=( error_code const & lhs, std::error_condition const & rhs ) noexcept
0481 {
0482 return !( lhs == rhs );
0483 }
0484
0485 inline friend bool operator!=( std::error_condition const & lhs, error_code const & rhs ) noexcept
0486 {
0487 return !( lhs == rhs );
0488 }
0489
0490 #endif
0491
0492
0493
0494 operator std::error_code () const
0495 {
0496 if( lc_flags_ == 1 )
0497 {
0498 return *reinterpret_cast<std::error_code const*>( d2_ );
0499 }
0500 else if( lc_flags_ == 0 )
0501 {
0502
0503 #if defined(BOOST_SYSTEM_AVOID_STD_SYSTEM_CATEGORY)
0504
0505 return std::error_code( 0, boost::system::system_category() );
0506
0507 #else
0508
0509 return std::error_code();
0510
0511 #endif
0512 }
0513 else
0514 {
0515 return std::error_code( d1_.val_, *d1_.cat_ );
0516 }
0517 }
0518
0519 operator std::error_code ()
0520 {
0521 return const_cast<error_code const&>( *this );
0522 }
0523
0524 template<class T,
0525 class E = typename detail::enable_if<detail::is_same<T, std::error_code>::value>::type>
0526 operator T& ()
0527 {
0528 if( lc_flags_ != 1 )
0529 {
0530 std::error_code e2( *this );
0531 ::new( d2_ ) std::error_code( e2 );
0532 lc_flags_ = 1;
0533 }
0534
0535 return *reinterpret_cast<std::error_code*>( d2_ );
0536 }
0537
0538 #if defined(BOOST_SYSTEM_CLANG_6)
0539
0540 template<class T,
0541 class E = typename std::enable_if<std::is_same<T, std::error_code>::value>::type>
0542 operator T const& () = delete;
0543
0544 #endif
0545
0546 std::string to_string() const
0547 {
0548 if( lc_flags_ == 1 )
0549 {
0550 std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( d2_ );
0551
0552 std::string r( "std:" );
0553 r += e2.category().name();
0554 detail::append_int( r, e2.value() );
0555
0556 return r;
0557 }
0558 else
0559 {
0560 std::string r = category_name();
0561 detail::append_int( r, value() );
0562 return r;
0563 }
0564 }
0565
0566 template<class Ch, class Tr>
0567 inline friend std::basic_ostream<Ch, Tr>&
0568 operator<< (std::basic_ostream<Ch, Tr>& os, error_code const & ec)
0569 {
0570 return os << ec.to_string().c_str();
0571 }
0572
0573 std::string what() const
0574 {
0575 std::string r = message();
0576
0577 r += " [";
0578 r += to_string();
0579
0580 if( has_location() )
0581 {
0582 r += " at ";
0583 r += location().to_string();
0584 }
0585
0586 r += "]";
0587 return r;
0588 }
0589 };
0590
0591 inline bool operator==( const error_code & code, const error_condition & condition ) noexcept
0592 {
0593 if( code.lc_flags_ == 1 )
0594 {
0595 return static_cast<std::error_code>( code ) == static_cast<std::error_condition>( condition );
0596 }
0597 else
0598 {
0599 return code.category().equivalent( code.value(), condition ) || condition.category().equivalent( code, condition.value() );
0600 }
0601 }
0602
0603 inline bool operator==( const error_condition & condition, const error_code & code ) noexcept
0604 {
0605 return code == condition;
0606 }
0607
0608 inline bool operator!=( const error_code & lhs, const error_condition & rhs ) noexcept
0609 {
0610 return !( lhs == rhs );
0611 }
0612
0613 inline bool operator!=( const error_condition & lhs, const error_code & rhs ) noexcept
0614 {
0615 return !( lhs == rhs );
0616 }
0617
0618 inline std::size_t hash_value( error_code const & ec )
0619 {
0620 if( ec.lc_flags_ == 1 )
0621 {
0622 std::error_code const& e2 = *reinterpret_cast<std::error_code const*>( ec.d2_ );
0623 return std::hash<std::error_code>()( e2 );
0624 }
0625
0626 error_category const & cat = ec.category();
0627
0628 boost::ulong_long_type id_ = cat.id_;
0629
0630 if( id_ == 0 )
0631 {
0632 id_ = reinterpret_cast<boost::uintptr_t>( &cat );
0633 }
0634
0635 boost::ulong_long_type hv = ( boost::ulong_long_type( 0xCBF29CE4 ) << 32 ) + 0x84222325;
0636 boost::ulong_long_type const prime = ( boost::ulong_long_type( 0x00000100 ) << 32 ) + 0x000001B3;
0637
0638
0639
0640 hv ^= id_;
0641 hv *= prime;
0642
0643
0644
0645 hv ^= static_cast<unsigned>( ec.value() );
0646 hv *= prime;
0647
0648 return static_cast<std::size_t>( hv );
0649 }
0650
0651 }
0652
0653 }
0654
0655 #if defined(BOOST_GCC) && BOOST_GCC >= 40600 && BOOST_GCC < 70000
0656 # pragma GCC diagnostic pop
0657 #endif
0658
0659 #endif