File indexing completed on 2025-01-18 09:52:35
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 BOOST_NOEXCEPT
0054 {
0055 return cat_? cat_->id_: detail::generic_category_id;
0056 }
0057
0058 public:
0059
0060
0061
0062 BOOST_SYSTEM_CONSTEXPR error_condition() BOOST_NOEXCEPT:
0063 val_( 0 ), cat_( 0 )
0064 {
0065 }
0066
0067 BOOST_SYSTEM_CONSTEXPR error_condition( int val, const error_category & cat ) BOOST_NOEXCEPT:
0068 val_( val ), cat_( &cat )
0069 {
0070 }
0071
0072 BOOST_SYSTEM_CONSTEXPR explicit error_condition( boost::system::detail::generic_value_tag vt ) BOOST_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) BOOST_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) BOOST_NOEXCEPT:
0087 val_( e ), cat_( 0 )
0088 {
0089 }
0090
0091
0092
0093 BOOST_SYSTEM_CONSTEXPR void assign( int val, const error_category & cat ) BOOST_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 ) BOOST_NOEXCEPT
0102 {
0103 *this = error_condition( val );
0104 return *this;
0105 }
0106
0107 BOOST_SYSTEM_CONSTEXPR void clear() BOOST_NOEXCEPT
0108 {
0109 val_ = 0;
0110 cat_ = 0;
0111 }
0112
0113
0114
0115 BOOST_SYSTEM_CONSTEXPR int value() const BOOST_NOEXCEPT
0116 {
0117 return val_;
0118 }
0119
0120 BOOST_SYSTEM_CONSTEXPR const error_category & category() const BOOST_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 BOOST_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 BOOST_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 #if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
0162
0163 BOOST_SYSTEM_CONSTEXPR explicit operator bool() const BOOST_NOEXCEPT
0164 {
0165 return failed();
0166 }
0167
0168 #else
0169
0170 typedef void (*unspecified_bool_type)();
0171 static void unspecified_bool_true() {}
0172
0173 BOOST_SYSTEM_CONSTEXPR operator unspecified_bool_type() const BOOST_NOEXCEPT
0174 {
0175 return failed()? unspecified_bool_true: 0;
0176 }
0177
0178 BOOST_SYSTEM_CONSTEXPR bool operator!() const BOOST_NOEXCEPT
0179 {
0180 return !failed();
0181 }
0182
0183 #endif
0184
0185
0186
0187
0188
0189 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
0190 {
0191 if( lhs.val_ != rhs.val_ )
0192 {
0193 return false;
0194 }
0195 else if( lhs.cat_ == 0 )
0196 {
0197 return rhs.cat_id() == detail::generic_category_id;
0198 }
0199 else if( rhs.cat_ == 0 )
0200 {
0201 return lhs.cat_id() == detail::generic_category_id;
0202 }
0203 else
0204 {
0205 return *lhs.cat_ == *rhs.cat_;
0206 }
0207 }
0208
0209 BOOST_SYSTEM_CONSTEXPR inline friend bool operator<( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
0210 {
0211 error_category const& lcat = lhs.category();
0212 error_category const& rcat = rhs.category();
0213 return lcat < rcat || ( lcat == rcat && lhs.val_ < rhs.val_ );
0214 }
0215
0216 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( const error_condition & lhs, const error_condition & rhs ) BOOST_NOEXCEPT
0217 {
0218 return !( lhs == rhs );
0219 }
0220
0221 #if defined(BOOST_SYSTEM_HAS_SYSTEM_ERROR)
0222
0223 operator std::error_condition () const
0224 {
0225
0226 #if defined(BOOST_SYSTEM_AVOID_STD_GENERIC_CATEGORY)
0227
0228 return std::error_condition( value(), category() );
0229
0230 #else
0231
0232 if( cat_ )
0233 {
0234 return std::error_condition( val_, *cat_ );
0235 }
0236 else
0237 {
0238 return std::error_condition( val_, std::generic_category() );
0239 }
0240
0241 #endif
0242 }
0243
0244 inline friend bool operator==( std::error_code const & lhs, error_condition const & rhs ) BOOST_NOEXCEPT
0245 {
0246 return lhs == static_cast< std::error_condition >( rhs );
0247 }
0248
0249 inline friend bool operator==( error_condition const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT
0250 {
0251 return static_cast< std::error_condition >( lhs ) == rhs;
0252 }
0253
0254 inline friend bool operator!=( std::error_code const & lhs, error_condition const & rhs ) BOOST_NOEXCEPT
0255 {
0256 return !( lhs == rhs );
0257 }
0258
0259 inline friend bool operator!=( error_condition const & lhs, std::error_code const & rhs ) BOOST_NOEXCEPT
0260 {
0261 return !( lhs == rhs );
0262 }
0263
0264
0265
0266 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0267 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( error_condition const & lhs, E rhs ) BOOST_NOEXCEPT
0268 {
0269 return lhs == make_error_condition( rhs );
0270 }
0271
0272 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0273 BOOST_SYSTEM_CONSTEXPR inline friend bool operator==( E lhs, error_condition const & rhs ) BOOST_NOEXCEPT
0274 {
0275 return make_error_condition( lhs ) == rhs;
0276 }
0277
0278 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0279 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( error_condition const & lhs, E rhs ) BOOST_NOEXCEPT
0280 {
0281 return !( lhs == rhs );
0282 }
0283
0284 template<class E, class N = typename detail::enable_if<std::is_error_condition_enum<E>::value>::type>
0285 BOOST_SYSTEM_CONSTEXPR inline friend bool operator!=( E lhs, error_condition const & rhs ) BOOST_NOEXCEPT
0286 {
0287 return !( lhs == rhs );
0288 }
0289
0290
0291
0292 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0293 inline friend bool operator==( error_condition const & lhs, E rhs ) BOOST_NOEXCEPT
0294 {
0295 return lhs == make_error_code( rhs );
0296 }
0297
0298 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0299 inline friend bool operator==( E lhs, error_condition const & rhs ) BOOST_NOEXCEPT
0300 {
0301 return make_error_code( lhs ) == rhs;
0302 }
0303
0304 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0305 inline friend bool operator!=( error_condition const & lhs, E rhs ) BOOST_NOEXCEPT
0306 {
0307 return !( lhs == rhs );
0308 }
0309
0310 template<class E, class N1 = void, class N2 = typename detail::enable_if<std::is_error_code_enum<E>::value>::type>
0311 inline friend bool operator!=( E lhs, error_condition const & rhs ) BOOST_NOEXCEPT
0312 {
0313 return !( lhs == rhs );
0314 }
0315
0316 #endif
0317
0318 std::string to_string() const
0319 {
0320 std::string r( "cond:" );
0321
0322 if( cat_ )
0323 {
0324 r += cat_->name();
0325 }
0326 else
0327 {
0328 r += "generic";
0329 }
0330
0331 detail::append_int( r, value() );
0332
0333 return r;
0334 }
0335
0336 template<class Ch, class Tr>
0337 inline friend std::basic_ostream<Ch, Tr>&
0338 operator<< (std::basic_ostream<Ch, Tr>& os, error_condition const & en)
0339 {
0340 os << en.to_string();
0341 return os;
0342 }
0343 };
0344
0345 }
0346
0347 }
0348
0349 #endif