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 | auto const ti = detail::get_type_index< | ||
41 | 7 | detail::get_key_type<T>>(); | |
42 | 7 | auto const ps = find_service_impl(ti); | |
43 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
7 | if(ps) |
44 | ✗ | detail::throw_invalid_argument( | |
45 | "service exists"); | ||
46 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
14 | return static_cast<T&>( |
47 | make_service_impl(ti, | ||
48 | 5 | std::unique_ptr<service>( | |
49 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
7 | new T(*this, std::forward< |
50 | 14 | Args>(args)...)))); | |
51 | } | ||
52 | |||
53 | template<class T> | ||
54 | T* | ||
55 | context:: | ||
56 | find_service() const noexcept | ||
57 | { | ||
58 | auto const ti = detail::get_type_index< | ||
59 | detail::get_key_type<T>>(); | ||
60 | auto const ps = find_service_impl(ti); | ||
61 | if(! ps) | ||
62 | return nullptr; | ||
63 | return dynamic_cast<T*>(ps); | ||
64 | } | ||
65 | |||
66 | template<class T> | ||
67 | bool | ||
68 | context:: | ||
69 | has_service() const noexcept | ||
70 | { | ||
71 | return find_service<T>() != nullptr; | ||
72 | } | ||
73 | |||
74 | template<class T> | ||
75 | T& | ||
76 | context:: | ||
77 | get_service() const | ||
78 | { | ||
79 | auto ps = find_service<T>(); | ||
80 | if(! ps) | ||
81 | detail::throw_invalid_argument( | ||
82 | "service not found"); | ||
83 | return *ps; | ||
84 | } | ||
85 | |||
86 | } // http_proto | ||
87 | } // boost | ||
88 | |||
89 | #endif | ||
90 |