1  
//
1  
//
2  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
2  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@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/boostorg/url
7  
// Official repository: https://github.com/boostorg/url
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_URL_DETAIL_OPTIONAL_STRING_HPP
10  
#ifndef BOOST_URL_DETAIL_OPTIONAL_STRING_HPP
11  
#define BOOST_URL_DETAIL_OPTIONAL_STRING_HPP
11  
#define BOOST_URL_DETAIL_OPTIONAL_STRING_HPP
12  

12  

13  
#include <boost/url/detail/string_view.hpp>
13  
#include <boost/url/detail/string_view.hpp>
14  
#include <boost/core/detail/string_view.hpp>
14  
#include <boost/core/detail/string_view.hpp>
15  

15  

16  
namespace boost {
16  
namespace boost {
17  
namespace urls {
17  
namespace urls {
18  

18  

19  
#ifndef BOOST_URL_DOCS
19  
#ifndef BOOST_URL_DOCS
20  
struct no_value_t;
20  
struct no_value_t;
21  
#endif
21  
#endif
22  

22  

23  
namespace detail {
23  
namespace detail {
24  
struct optional_string
24  
struct optional_string
25  
{
25  
{
26  
    core::string_view s;
26  
    core::string_view s;
27  
    bool b = false;
27  
    bool b = false;
28  
};
28  
};
29  

29  

30  
template <class String>
30  
template <class String>
31  
typename std::enable_if<
31  
typename std::enable_if<
32  
    std::is_convertible<String, core::string_view>::value,
32  
    std::is_convertible<String, core::string_view>::value,
33  
    optional_string>::type
33  
    optional_string>::type
34  
get_optional_string(
34  
get_optional_string(
35  
    String const& s)
35  
    String const& s)
36  
{
36  
{
37  
    optional_string r;
37  
    optional_string r;
38  
    r.s = s;
38  
    r.s = s;
39  
    r.b = true;
39  
    r.b = true;
40  
    return r;
40  
    return r;
41  
}
41  
}
42  

42  

43  
template <class T, class = void>
43  
template <class T, class = void>
44  
struct is_dereferenceable : std::false_type
44  
struct is_dereferenceable : std::false_type
45  
{};
45  
{};
46  

46  

47  
template <class T>
47  
template <class T>
48  
struct is_dereferenceable<
48  
struct is_dereferenceable<
49  
    T,
49  
    T,
50  
    void_t<
50  
    void_t<
51  
        decltype(*std::declval<T>())
51  
        decltype(*std::declval<T>())
52  
        >> : std::true_type
52  
        >> : std::true_type
53  
{};
53  
{};
54  

54  

55  
template <class OptionalString>
55  
template <class OptionalString>
56  
typename std::enable_if<
56  
typename std::enable_if<
57  
    !std::is_convertible<OptionalString, core::string_view>::value,
57  
    !std::is_convertible<OptionalString, core::string_view>::value,
58  
    optional_string>::type
58  
    optional_string>::type
59  
get_optional_string(
59  
get_optional_string(
60  
    OptionalString const& opt)
60  
    OptionalString const& opt)
61  
{
61  
{
62  
    // If this goes off, it means the rule
62  
    // If this goes off, it means the rule
63  
    // passed in did not meet the requirements.
63  
    // passed in did not meet the requirements.
64  
    // Please check the documentation of functions
64  
    // Please check the documentation of functions
65  
    // that call get_optional_string.
65  
    // that call get_optional_string.
66  
    static_assert(
66  
    static_assert(
67  
        is_dereferenceable<OptionalString>::value &&
67  
        is_dereferenceable<OptionalString>::value &&
68  
        std::is_constructible<bool, OptionalString>::value &&
68  
        std::is_constructible<bool, OptionalString>::value &&
69  
        !std::is_convertible<OptionalString, core::string_view>::value &&
69  
        !std::is_convertible<OptionalString, core::string_view>::value &&
70  
        std::is_convertible<typename std::decay<decltype(*std::declval<OptionalString>())>::type, core::string_view>::value,
70  
        std::is_convertible<typename std::decay<decltype(*std::declval<OptionalString>())>::type, core::string_view>::value,
71  
        "OptionalString requirements not met");
71  
        "OptionalString requirements not met");
72  
    optional_string r;
72  
    optional_string r;
73  
    r.s = opt ? detail::to_sv(*opt) : core::string_view{};
73  
    r.s = opt ? detail::to_sv(*opt) : core::string_view{};
74  
    r.b = static_cast<bool>(opt);
74  
    r.b = static_cast<bool>(opt);
75  
    return r;
75  
    return r;
76  
}
76  
}
77  

77  

78  
inline
78  
inline
79  
optional_string
79  
optional_string
80  
get_optional_string(
80  
get_optional_string(
81  
    std::nullptr_t)
81  
    std::nullptr_t)
82  
{
82  
{
83  
    return {};
83  
    return {};
84  
}
84  
}
85  

85  

86  
inline
86  
inline
87  
optional_string
87  
optional_string
88  
get_optional_string(
88  
get_optional_string(
89  
    no_value_t const&)
89  
    no_value_t const&)
90  
{
90  
{
91  
    return {};
91  
    return {};
92  
}
92  
}
93  

93  

94  

94  

95  
} // detail
95  
} // detail
96  
} // urls
96  
} // urls
97  
} // boost
97  
} // boost
98  

98  

99  
#endif
99  
#endif