Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) | ||
3 | // | ||
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) | ||
6 | // | ||
7 | // Official repository: https://github.com/cppalliance/http_proto | ||
8 | // | ||
9 | |||
10 | #ifndef BOOST_HTTP_PROTO_IMPL_CONTEXT_HPP | ||
11 | #define BOOST_HTTP_PROTO_IMPL_CONTEXT_HPP | ||
12 | |||
13 | #include <boost/http_proto/detail/except.hpp> | ||
14 | #include <boost/http_proto/detail/type_index.hpp> | ||
15 | |||
16 | #include <boost/mp11/utility.hpp> | ||
17 | #include <utility> | ||
18 | |||
19 | namespace boost { | ||
20 | namespace http_proto { | ||
21 | |||
22 | namespace detail { | ||
23 | |||
24 | template<class T> | ||
25 | using get_key_impl = | ||
26 | typename T::key_type; | ||
27 | |||
28 | template<class T> | ||
29 | using get_key_type = | ||
30 | mp11::mp_eval_or<T, get_key_impl, T>; | ||
31 | |||
32 | } // detail | ||
33 | |||
34 | //------------------------------------------------ | ||
35 | |||
36 | template<class T, class... Args> | ||
37 | T& | ||
38 | 32 | context:: | |
39 | make_service( | ||
40 | Args&&... args) | ||
41 | { | ||
42 | static_assert( | ||
43 | std::is_base_of<service, T>::value, | ||
44 | "Type requirements not met."); | ||
45 | |||
46 | auto const ti = detail::get_type_index< | ||
47 | 32 | detail::get_key_type<T>>(); | |
48 | 32 | auto const ps = find_service_impl(ti); | |
49 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
|
32 | if(ps) |
50 | ✗ | detail::throw_invalid_argument( | |
51 | "service exists"); | ||
52 |
2/4✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 32 times.
✗ Branch 6 not taken.
|
64 | return detail::downcast<T&>( |
53 | make_service_impl(ti, | ||
54 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | std::unique_ptr<service>( |
55 |
2/4✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
|
32 | new T(*this, std::forward< |
56 | 95 | Args>(args)...)))); | |
57 | } | ||
58 | |||
59 | template<class T> | ||
60 | T* | ||
61 | 1583 | context:: | |
62 | find_service() const noexcept | ||
63 | { | ||
64 | auto const ti = detail::get_type_index< | ||
65 | 1583 | detail::get_key_type<T>>(); | |
66 | 1583 | auto const ps = find_service_impl(ti); | |
67 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 792 times.
|
1583 | if(! ps) |
68 | ✗ | return nullptr; | |
69 | 1583 | return detail::downcast<T*>(ps); | |
70 | } | ||
71 | |||
72 | template<class T> | ||
73 | bool | ||
74 | context:: | ||
75 | has_service() const noexcept | ||
76 | { | ||
77 | return find_service<T>() != nullptr; | ||
78 | } | ||
79 | |||
80 | template<class T> | ||
81 | T& | ||
82 | 791 | context:: | |
83 | get_service() const | ||
84 | { | ||
85 | 791 | auto ps = find_service<T>(); | |
86 | 791 | if(! ps) | |
87 | ✗ | detail::throw_invalid_argument( | |
88 | "service not found"); | ||
89 | 791 | return *ps; | |
90 | } | ||
91 | |||
92 | } // http_proto | ||
93 | } // boost | ||
94 | |||
95 | #endif | ||
96 |