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/mp11/utility.hpp> | ||
15 | #include <utility> | ||
16 | |||
17 | namespace boost { | ||
18 | namespace http_proto { | ||
19 | |||
20 | namespace detail { | ||
21 | |||
22 | template<class T> | ||
23 | using get_key_impl = | ||
24 | typename T::key_type; | ||
25 | |||
26 | template<class T> | ||
27 | using get_key_type = | ||
28 | mp11::mp_eval_or<T, get_key_impl, T>; | ||
29 | |||
30 | } // detail | ||
31 | |||
32 | //------------------------------------------------ | ||
33 | |||
34 | template<class T, class... Args> | ||
35 | T& | ||
36 | 7 | context:: | |
37 | make_service( | ||
38 | Args&&... args) | ||
39 | { | ||
40 | static_assert( | ||
41 | std::is_base_of<service, T>::value, | ||
42 | "Type requirements not met."); | ||
43 | |||
44 | auto const ti = detail::get_type_index< | ||
45 | 7 | detail::get_key_type<T>>(); | |
46 | 7 | auto const ps = find_service_impl(ti); | |
47 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if(ps) |
48 | ✗ | detail::throw_invalid_argument( | |
49 | "service exists"); | ||
50 |
1/2✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
14 | return static_cast<T&>( |
51 | make_service_impl(ti, | ||
52 | std::unique_ptr<service>( | ||
53 |
1/2✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
7 | new T(*this, std::forward< |
54 | 21 | Args>(args)...)))); | |
55 | } | ||
56 | |||
57 | template<class T> | ||
58 | T* | ||
59 | 1472 | context:: | |
60 | find_service() const noexcept | ||
61 | { | ||
62 | auto const ti = detail::get_type_index< | ||
63 | 1472 | detail::get_key_type<T>>(); | |
64 | 1472 | auto const ps = find_service_impl(ti); | |
65 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 736 times.
|
1472 | if(! ps) |
66 | ✗ | return nullptr; | |
67 |
1/2✓ Branch 0 taken 736 times.
✗ Branch 1 not taken.
|
1472 | return dynamic_cast<T*>(ps); |
68 | } | ||
69 | |||
70 | template<class T> | ||
71 | bool | ||
72 | context:: | ||
73 | has_service() const noexcept | ||
74 | { | ||
75 | return find_service<T>() != nullptr; | ||
76 | } | ||
77 | |||
78 | template<class T> | ||
79 | T& | ||
80 | 736 | context:: | |
81 | get_service() const | ||
82 | { | ||
83 | 736 | auto ps = find_service<T>(); | |
84 | 736 | if(! ps) | |
85 | ✗ | detail::throw_invalid_argument( | |
86 | "service not found"); | ||
87 | 736 | return *ps; | |
88 | } | ||
89 | |||
90 | } // http_proto | ||
91 | } // boost | ||
92 | |||
93 | #endif | ||
94 |