1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/capy
7  
// Official repository: https://github.com/cppalliance/capy
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_CAPY_COND_HPP
10  
#ifndef BOOST_CAPY_COND_HPP
11  
#define BOOST_CAPY_COND_HPP
11  
#define BOOST_CAPY_COND_HPP
12  

12  

13  
#include <boost/capy/detail/config.hpp>
13  
#include <boost/capy/detail/config.hpp>
14  
#include <system_error>
14  
#include <system_error>
15  

15  

16  
namespace boost {
16  
namespace boost {
17  
namespace capy {
17  
namespace capy {
18  

18  

19  
/** Portable error conditions for capy I/O operations.
19  
/** Portable error conditions for capy I/O operations.
20  

20  

21  
    These are the conditions callers should compare against when
21  
    These are the conditions callers should compare against when
22  
    handling errors from capy operations. The @ref error enum values
22  
    handling errors from capy operations. The @ref error enum values
23  
    map to these conditions, as do platform-specific error codes
23  
    map to these conditions, as do platform-specific error codes
24  
    (e.g., `ECANCELED`, SSL EOF errors).
24  
    (e.g., `ECANCELED`, SSL EOF errors).
25  

25  

26  
    @par Example
26  
    @par Example
27  

27  

28  
    @code
28  
    @code
29  
    auto [ec, n] = co_await stream.read_some( bufs );
29  
    auto [ec, n] = co_await stream.read_some( bufs );
30  
    if( ec == cond::canceled )
30  
    if( ec == cond::canceled )
31  
        // handle cancellation
31  
        // handle cancellation
32  
    else if( ec == cond::eof )
32  
    else if( ec == cond::eof )
33  
        // handle end of stream
33  
        // handle end of stream
34  
    else if( ec.failed() )
34  
    else if( ec.failed() )
35  
        // handle other errors
35  
        // handle other errors
36  
    @endcode
36  
    @endcode
37  

37  

38  
    @see error
38  
    @see error
39  
*/
39  
*/
40  
enum class cond
40  
enum class cond
41  
{
41  
{
42  
    /** End-of-stream condition.
42  
    /** End-of-stream condition.
43  

43  

44  
        An `error_code` compares equal to `eof` when the stream
44  
        An `error_code` compares equal to `eof` when the stream
45  
        reached its natural end, such as when a peer sends TCP FIN
45  
        reached its natural end, such as when a peer sends TCP FIN
46  
        or a file reaches EOF.
46  
        or a file reaches EOF.
47  
    */
47  
    */
48  
    eof = 1,
48  
    eof = 1,
49  

49  

50  
    /** Operation cancelled condition.
50  
    /** Operation cancelled condition.
51  

51  

52  
        An `error_code` compares equal to `canceled` when the
52  
        An `error_code` compares equal to `canceled` when the
53  
        operation's stop token was activated, the I/O object's
53  
        operation's stop token was activated, the I/O object's
54  
        `cancel()` was called, or a platform cancellation error
54  
        `cancel()` was called, or a platform cancellation error
55  
        occurred.
55  
        occurred.
56  
    */
56  
    */
57  
    canceled = 2,
57  
    canceled = 2,
58  

58  

59  
    /** Stream truncated condition.
59  
    /** Stream truncated condition.
60  

60  

61  
        An `error_code` compares equal to `stream_truncated` when
61  
        An `error_code` compares equal to `stream_truncated` when
62  
        a TLS peer closed the connection without sending a proper
62  
        a TLS peer closed the connection without sending a proper
63  
        shutdown alert.
63  
        shutdown alert.
64  
    */
64  
    */
65  
    stream_truncated = 3,
65  
    stream_truncated = 3,
66  

66  

67  
    /** Item not found condition.
67  
    /** Item not found condition.
68  

68  

69  
        An `error_code` compares equal to `not_found` when a
69  
        An `error_code` compares equal to `not_found` when a
70  
        lookup operation failed to find the requested item.
70  
        lookup operation failed to find the requested item.
71  
    */
71  
    */
72  
    not_found = 4
72  
    not_found = 4
73  
};
73  
};
74  

74  

75  
//-----------------------------------------------
75  
//-----------------------------------------------
76  

76  

77  
} // capy
77  
} // capy
78  
} // boost
78  
} // boost
79  

79  

80  
namespace std {
80  
namespace std {
81  
template<>
81  
template<>
82  
struct is_error_condition_enum<
82  
struct is_error_condition_enum<
83  
    ::boost::capy::cond>
83  
    ::boost::capy::cond>
84  
    : std::true_type {};
84  
    : std::true_type {};
85  
} // std
85  
} // std
86  

86  

87  
namespace boost {
87  
namespace boost {
88  
namespace capy {
88  
namespace capy {
89  

89  

90  
//-----------------------------------------------
90  
//-----------------------------------------------
91  

91  

92  
namespace detail {
92  
namespace detail {
93  

93  

94  
struct BOOST_CAPY_SYMBOL_VISIBLE
94  
struct BOOST_CAPY_SYMBOL_VISIBLE
95  
    cond_cat_type
95  
    cond_cat_type
96  
    : std::error_category
96  
    : std::error_category
97  
{
97  
{
98  
    BOOST_CAPY_DECL const char* name(
98  
    BOOST_CAPY_DECL const char* name(
99  
        ) const noexcept override;
99  
        ) const noexcept override;
100  
    BOOST_CAPY_DECL std::string message(
100  
    BOOST_CAPY_DECL std::string message(
101  
        int) const override;
101  
        int) const override;
102  
    BOOST_CAPY_DECL bool equivalent(
102  
    BOOST_CAPY_DECL bool equivalent(
103  
        std::error_code const& ec,
103  
        std::error_code const& ec,
104  
        int condition) const noexcept override;
104  
        int condition) const noexcept override;
105  
    constexpr cond_cat_type() noexcept = default;
105  
    constexpr cond_cat_type() noexcept = default;
106  
};
106  
};
107  

107  

108  
BOOST_CAPY_DECL extern cond_cat_type cond_cat;
108  
BOOST_CAPY_DECL extern cond_cat_type cond_cat;
109  

109  

110  
} // detail
110  
} // detail
111  

111  

112  
//-----------------------------------------------
112  
//-----------------------------------------------
113  

113  

114  
inline
114  
inline
115  
std::error_condition
115  
std::error_condition
116  
make_error_condition(
116  
make_error_condition(
117  
    cond ev) noexcept
117  
    cond ev) noexcept
118  
{
118  
{
119  
    return std::error_condition{
119  
    return std::error_condition{
120  
        static_cast<std::underlying_type<
120  
        static_cast<std::underlying_type<
121  
            cond>::type>(ev),
121  
            cond>::type>(ev),
122  
        detail::cond_cat};
122  
        detail::cond_cat};
123  
}
123  
}
124  

124  

125  
} // capy
125  
} // capy
126  
} // boost
126  
} // boost
127  

127  

128  
#endif
128  
#endif