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 )
34  
    else if( ec )
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  
    /** Operation timed out condition.
74  
    /** Operation timed out condition.
75  

75  

76  
        An `error_code` compares equal to `timeout` when an
76  
        An `error_code` compares equal to `timeout` when an
77  
        operation exceeded its allowed duration.
77  
        operation exceeded its allowed duration.
78  
    */
78  
    */
79  
    timeout = 5
79  
    timeout = 5
80  
};
80  
};
81  

81  

82  
} // capy
82  
} // capy
83  
} // boost
83  
} // boost
84  

84  

85  
namespace std {
85  
namespace std {
86  
template<>
86  
template<>
87  
struct is_error_condition_enum<
87  
struct is_error_condition_enum<
88  
    ::boost::capy::cond>
88  
    ::boost::capy::cond>
89  
    : std::true_type {};
89  
    : std::true_type {};
90  
} // std
90  
} // std
91  

91  

92  
namespace boost {
92  
namespace boost {
93  
namespace capy {
93  
namespace capy {
94  

94  

95  
namespace detail {
95  
namespace detail {
96  

96  

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

110  

111  
BOOST_CAPY_DECL extern cond_cat_type cond_cat;
111  
BOOST_CAPY_DECL extern cond_cat_type cond_cat;
112  

112  

113  
} // detail
113  
} // detail
114  

114  

115  
/// Create an error_condition from a cond value.
115  
/// Create an error_condition from a cond value.
116  
inline
116  
inline
117  
std::error_condition
117  
std::error_condition
118  
make_error_condition(
118  
make_error_condition(
119  
    cond ev) noexcept
119  
    cond ev) noexcept
120  
{
120  
{
121  
    return std::error_condition{
121  
    return std::error_condition{
122  
        static_cast<std::underlying_type<
122  
        static_cast<std::underlying_type<
123  
            cond>::type>(ev),
123  
            cond>::type>(ev),
124  
        detail::cond_cat};
124  
        detail::cond_cat};
125  
}
125  
}
126  

126  

127  
} // capy
127  
} // capy
128  
} // boost
128  
} // boost
129  

129  

130  
#endif
130  
#endif