File indexing completed on 2025-06-30 08:31:23
0001 #ifndef BOOST_SYSTEM_DETAIL_ERROR_CONDITION_HPP_INCLUDED
0002 #define BOOST_SYSTEM_DETAIL_ERROR_CONDITION_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <boost/system/detail/error_category.hpp>
0014 #include <boost/system/detail/generic_category.hpp>
0015 #include <boost/system/detail/enable_if.hpp>
0016 #include <boost/system/detail/is_same.hpp>
0017 #include <boost/system/detail/errc.hpp>
0018 #include <boost/system/detail/append_int.hpp>
0019 #include <boost/system/is_error_condition_enum.hpp>
0020 #include <boost/system/detail/config.hpp>
0021 #include <boost/config.hpp>
0022
0023 namespace boost
0024 {
0025
0026 namespace system
0027 {
0028
0029
0030
0031
0032
0033 namespace detail
0034 {
0035
0036 struct generic_value_tag
0037 {
0038 int value;
0039 BOOST_SYSTEM_CONSTEXPR explicit generic_value_tag( int v ): value( v ) {}
0040 };
0041
0042 }
0043
0044 class error_condition
0045 {
0046 private:
0047
0048 int val_;
0049 error_category const * cat_;
0050
0051 private:
0052
0053 boost::ulong_long_type cat_id() const noexcept
0054 {
0055 return cat_? cat_->id_: detail::generic_category_id;
0056 }
0057
0058 public:
0059
0060
0061
0062 BOOST_SYSTEM_CONSTEXPR error_condition() noexcept:
0063 val_( 0 ), cat_( 0 )
0064 {
0065 }
0066
0067 BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) noexcept:
0068 val_( val ), cat_( &cat )
0069 {
0070 }
0071
0072 BOOST_SYSTEM_CONSTEXPR explicit error_condition( boost::system::detail::generic_value_tag vt ) noexcept:
0073 val_( vt.value ), cat_( 0 )
0074 {
0075 }
0076
0077 template<class ErrorConditionEnum> BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e,
0078 typename detail::enable_if<
0079 is_error_condition_enum<ErrorConditionEnum>::value && !boost::system::detail::is_same<ErrorConditionEnum, errc::errc_t>::value
0080 >::type* = 0) noexcept
0081 {
0082 *this = make_error_condition( e );
0083 }
0084
0085 template<class ErrorConditionEnum> BOOST_SYSTEM_CONSTEXPR error_condition( ErrorConditionEnum e,
0086 typename detail::enable_if<boost::system::detail::is_same<ErrorConditionEnum, errc::errc_t>::value>::type* = 0) noexcept:
0087 val_( e ), cat_( 0 )
0088 {
0089 }
0090
0091
0092
0093 BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) noexcept
0094 {
0095 val_ = val;
0096 cat_ = &cat;
0097 }
0098
0099 template<typename ErrorConditionEnum>
0100 BOOST_SYSTEM_CONSTEXPR typename detail::enable_if<is_error_condition_enum<ErrorConditionEnum>::value, error_condition>::type &
0101 operator=( ErrorConditionEnum val ) noexcept
0102 {
0103 *this = error_condition( val );
0104 return *this;
0105 }
0106
0107 BOOST_SYSTEM_CONSTEXPR void clear() noexcept
0108 {
0109 val_ = 0;
0110 cat_ = 0;
0111 }
0112
0113
0114
0115 BOOST_SYSTEM_CONSTEXPR int value() const noexcept
0116 {
0117 return val_;
0118 }
0119
0120 BOOST_SYSTEM_CONSTEXPR const error_category & category() const noexcept
0121 {
0122 return cat_? *cat_: generic_category();
0123 }
0124
0125 std::string message() const
0126 {
0127 if( cat_ )
0128 {
0129 return cat_->message( value() );
0130 }
0131 else
0132 {
0133 return detail::generic_error_category_message( value() );
0134 }
0135 }
0136
0137 char const * message( char * buffer, std::size_t len ) const noexcept
0138 {
0139 if( cat_ )
0140 {
0141 return cat_->message( value(), buffer, len );
0142 }
0143 else
0144 {
0145 return detail::generic_error_category_message( value(), buffer, len );
0146 }
0147 }
0148
0149 BOOST_SYSTEM_CONSTEXPR bool failed() const noexcept
0150 {
0151 if( cat_ )
0152 {
0153 return detail::failed_impl( val_, *cat_ );
0154 }
0155 else
0156 {
0157 return val_ != 0;
0158 }
0159 }
0160
0161 BOOST_SYSTEM_CONSTEXPR explicit operator bool() const noexcept
0162 {
0163 return failed();
0164 }
0165
0166
0167
0168
0169
0170 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) noexcept
0171 {
0172 if( lhs.val_ != rhs.val_ )
0173 {
0174 return false;
0175 }
0176 else if( lhs.cat_ == 0 )
0177 {
0178 return rhs.cat_id() == detail::generic_category_id;
0179 }
0180 else if( rhs.cat_ == 0 )
0181 {
0182 return lhs.cat_id() == detail::generic_category_id;
0183 }
0184 else
0185 {
0186 return *lhs.cat_ == *rhs.cat_;
0187 }
0188 }
0189
0190 BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) noexcept
0191 {
0192 error_category const& lcat = lhs.category();
0193 error_category const& rcat = rhs.category();
0194 return lcat < rcat || ( lcat == rcat && lhs.val_ < rhs.val_ );
0195 }
0196
0197 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_condition & lhs, const error_condition & rhs ) noexcept
0198 {
0199 return !( lhs == rhs );
0200 }
0201
0202 operator std::error_condition () const
0203 {
0204
0205 #if defined(BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY)
0206
0207 return std::error_condition( value(), category() );
0208
0209 #else
0210
0211 if( cat_ )
0212 {
0213 return std::error_condition( val_, *cat_ );
0214 }
0215 else
0216 {
0217 return std::error_condition( val_, std::generic_category() );
0218 }
0219
0220 #endif
0221 }
0222
0223 inline friend bool operator==( std::error_code const & lhs, error_condition const & rhs ) noexcept
0224 {
0225 return lhs == static_cast< std::error_condition >( rhs );
0226 }
0227
0228 inline friend bool operator==( error_condition const & lhs, std::error_code const & rhs ) noexcept
0229 {
0230 return static_cast< std::error_condition >( lhs ) == rhs;
0231 }
0232
0233 inline friend bool operator!=( std::error_code const & lhs, error_condition const & rhs ) noexcept
0234 {
0235 return !( lhs == rhs );
0236 }
0237
0238 inline friend bool operator!=( error_condition const & lhs, std::error_code const & rhs ) noexcept
0239 {
0240 return !( lhs == rhs );
0241 }
0242
0243
0244
0245 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0246 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( error_condition const & lhs, E rhs ) noexcept
0247 {
0248 return lhs == make_error_condition( rhs );
0249 }
0250
0251 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0252 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( E lhs, error_condition const & rhs ) noexcept
0253 {
0254 return make_error_condition( lhs ) == rhs;
0255 }
0256
0257 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0258 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( error_condition const & lhs, E rhs ) noexcept
0259 {
0260 return !( lhs == rhs );
0261 }
0262
0263 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0264 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( E lhs, error_condition const & rhs ) noexcept
0265 {
0266 return !( lhs == rhs );
0267 }
0268
0269
0270
0271 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0272 inline friend bool operator==( error_condition const & lhs, E rhs ) noexcept
0273 {
0274 return lhs == make_error_code( rhs );
0275 }
0276
0277 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0278 inline friend bool operator==( E lhs, error_condition const & rhs ) noexcept
0279 {
0280 return make_error_code( lhs ) == rhs;
0281 }
0282
0283 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0284 inline friend bool operator!=( error_condition const & lhs, E rhs ) noexcept
0285 {
0286 return !( lhs == rhs );
0287 }
0288
0289 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0290 inline friend bool operator!=( E lhs, error_condition const & rhs ) noexcept
0291 {
0292 return !( lhs == rhs );
0293 }
0294
0295 std::string to_string() const
0296 {
0297 std::string r( "cond:" );
0298
0299 if( cat_ )
0300 {
0301 r += cat_->name();
0302 }
0303 else
0304 {
0305 r += "generic";
0306 }
0307
0308 detail::append_int( r, value() );
0309
0310 return r;
0311 }
0312
0313 template<class Ch, class Tr>
0314 inline friend std::basic_ostream<Ch, Tr>&
0315 operator<< (std::basic_ostream<Ch, Tr>& os, error_condition const & en)
0316 {
0317 os << en.to_string();
0318 return os;
0319 }
0320 };
0321
0322 }
0323
0324 }
0325
0326 #endif