// // Copyright (c) 2012-2017 Kris Jusiak (kris at jusiak dot net) // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once #if (__cplusplus < 201305L && _MSC_VER < 1900) #error "[Boost].DI requires C++14 support (Clang-3.4+, GCC-5.1+, MSVC-2015+)" #else #define BOOST_DI_VERSION 1'1'0 #define BOOST_DI_NAMESPACE_BEGIN \ namespace boost { \ namespace di { \ inline namespace v1_1_0 { #define BOOST_DI_NAMESPACE_END \ } \ } \ } #if !defined(BOOST_DI_CFG_DIAGNOSTICS_LEVEL) #define BOOST_DI_CFG_DIAGNOSTICS_LEVEL 1 #endif #if defined(BOOST_DI_CFG_FWD) BOOST_DI_CFG_FWD #endif #define __BOOST_DI_COMPILER(arg, ...) __BOOST_DI_COMPILER_IMPL(arg, __VA_ARGS__) #define __BOOST_DI_COMPILER_IMPL(arg, ...) arg##__VA_ARGS__ #if defined(__clang__) #define __CLANG__ __BOOST_DI_COMPILER(__clang_major__, __clang_minor__) #define __BOOST_DI_UNUSED __attribute__((unused)) #define __BOOST_DI_DEPRECATED(...) [[deprecated(__VA_ARGS__)]] #define __BOOST_DI_TYPE_WKND(T) #define __BOOST_DI_ACCESS_WKND private #elif defined(__GNUC__) #define __GCC__ #define __BOOST_DI_UNUSED __attribute__((unused)) #define __BOOST_DI_DEPRECATED(...) [[deprecated(__VA_ARGS__)]] #define __BOOST_DI_TYPE_WKND(T) #define __BOOST_DI_ACCESS_WKND private #elif defined(_MSC_VER) #define __MSVC__ #define __has_include(...) 0 #define __BOOST_DI_UNUSED #define __BOOST_DI_DEPRECATED(...) __declspec(deprecated(__VA_ARGS__)) #define __BOOST_DI_TYPE_WKND(T) (T &&) #define __BOOST_DI_ACCESS_WKND public #endif #if !defined(__has_builtin) #define __has_builtin(...) 0 #endif #if !defined(__has_extension) #define __has_extension(...) 0 #endif #if defined(__CLANG__) #if (!BOOST_DI_CFG_DIAGNOSTICS_LEVEL) #pragma clang diagnostic error "-Wdeprecated-declarations" #else #pragma clang diagnostic warning "-Wdeprecated-declarations" #endif #pragma clang diagnostic push #pragma clang diagnostic error "-Wundefined-inline" #pragma clang diagnostic error "-Wundefined-internal" #pragma clang diagnostic ignored "-Wmissing-field-initializers" #elif defined(__GCC__) #pragma GCC diagnostic error "-Wdeprecated-declarations" #pragma GCC diagnostic push #if (__GNUC__ < 6) #pragma GCC diagnostic error "-Werror" #endif #elif defined(__MSVC__) #pragma warning(disable : 4503) #pragma warning(disable : 4822) #pragma warning(disable : 4505) #endif #if __has_include(<__config>) #include <__config> #endif #if defined(_LIBCPP_VERSION) _LIBCPP_BEGIN_NAMESPACE_STD #else namespace std { #endif template class shared_ptr; template class weak_ptr; template class unique_ptr; template struct char_traits; template class tuple; template class vector; template class set; template class move_iterator; #if defined(_LIBCPP_VERSION) _LIBCPP_END_NAMESPACE_STD #else } #endif namespace std { template class initializer_list; } namespace boost { template class shared_ptr; } BOOST_DI_NAMESPACE_BEGIN struct _ { _(...) {} }; namespace aux { using swallow = int[]; template using owner = T; template struct valid { using type = int; }; template using valid_t = typename valid::type; template struct type {}; struct none_type {}; template struct non_type {}; template struct always { static constexpr auto value = true; }; template struct never { static constexpr auto value = false; }; template struct identity { using type = T; }; template struct type_list { using type = type_list; }; template struct bool_list { using type = bool_list; }; template struct pair { using type = pair; using first = T1; using second = T2; }; template struct inherit : Ts... { using type = inherit; }; template struct join { using type = type_list<>; }; template struct join { using type = T; }; template struct join, type_list, Ts...> : join, Ts...> {}; template struct join, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, type_list, Us...> : join, Us...> {}; template using join_t = typename join::type; template struct index_sequence { using type = index_sequence; }; #if __has_builtin(__make_integer_seq) template struct integer_sequence; template struct integer_sequence { using type = index_sequence; }; template struct make_index_sequence_impl { using type = typename __make_integer_seq::type; }; #else template struct make_index_sequence_impl; template <> struct make_index_sequence_impl<0> : index_sequence<> {}; template <> struct make_index_sequence_impl<1> : index_sequence<0> {}; template <> struct make_index_sequence_impl<2> : index_sequence<0, 1> {}; template <> struct make_index_sequence_impl<3> : index_sequence<0, 1, 2> {}; template <> struct make_index_sequence_impl<4> : index_sequence<0, 1, 2, 3> {}; template <> struct make_index_sequence_impl<5> : index_sequence<0, 1, 2, 3, 4> {}; template <> struct make_index_sequence_impl<6> : index_sequence<0, 1, 2, 3, 4, 5> {}; template <> struct make_index_sequence_impl<7> : index_sequence<0, 1, 2, 3, 4, 5, 6> {}; template <> struct make_index_sequence_impl<8> : index_sequence<0, 1, 2, 3, 4, 5, 6, 7> {}; template <> struct make_index_sequence_impl<9> : index_sequence<0, 1, 2, 3, 4, 5, 6, 7, 8> {}; template <> struct make_index_sequence_impl<10> : index_sequence<0, 1, 2, 3, 4, 5, 6, 7, 8, 9> {}; #endif template using make_index_sequence = typename make_index_sequence_impl::type; } template struct named {}; struct no_name { constexpr auto operator()() const noexcept { return ""; } }; template struct ctor_traits; template struct self {}; struct ignore_policies {}; namespace core { template struct any_type_fwd; template struct any_type_ref_fwd; template struct any_type_1st_fwd; template struct any_type_1st_ref_fwd; struct dependency_base {}; struct injector_base {}; template struct dependency__ : T { using T::try_create; using T::is_referable; using T::create; }; template struct injector__ : T { using T::try_create; using T::create_impl; using T::create_successful_impl; #if defined(__MSVC__) template using is_creatable = typename T::template is_creatable; #else using T::is_creatable; #endif }; template struct array; struct deduced {}; template class dependency; } namespace scopes { class deduce; class instance; class singleton; class unique; } #define __BOOST_DI_REQUIRES(...) typename ::boost::di::v1_1_0::aux::enable_if<__VA_ARGS__, int>::type #define __BOOST_DI_REQUIRES_MSG(...) typename ::boost::di::v1_1_0::aux::concept_check<__VA_ARGS__>::type namespace aux { template T&& declval(); template struct integral_constant { using type = integral_constant; static constexpr T value = V; }; using true_type = integral_constant; using false_type = integral_constant; template struct conditional { using type = T; }; template struct conditional { using type = F; }; template using conditional_t = typename conditional::type; template struct enable_if {}; template struct enable_if { using type = T; }; template using enable_if_t = typename enable_if::type; template struct concept_check { static_assert(T::value, "constraint not satisfied"); }; template <> struct concept_check { using type = int; }; template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; template using remove_reference_t = typename remove_reference::type; template struct remove_pointer { using type = T; }; template struct remove_pointer { using type = T; }; template using remove_pointer_t = typename remove_pointer::type; template struct remove_smart_ptr { using type = T; }; template struct remove_smart_ptr> { using type = T; }; template struct remove_smart_ptr> { using type = T; }; template struct remove_smart_ptr> { using type = T; }; template struct remove_smart_ptr> { using type = T; }; template using remove_smart_ptr_t = typename remove_smart_ptr::type; template struct remove_qualifiers { using type = T; }; template struct remove_qualifiers { using type = T; }; template struct remove_qualifiers { using type = T; }; template struct remove_qualifiers { using type = T; }; template struct remove_qualifiers { using type = T; }; template struct remove_qualifiers { using type = T; }; template struct remove_qualifiers { using type = T; }; template struct remove_qualifiers { using type = T; }; template struct remove_qualifiers { using type = T; }; template struct remove_qualifiers { using type = T; }; template using remove_qualifiers_t = typename remove_qualifiers::type; template struct remove_extent { using type = T; }; template struct remove_extent { using type = T; }; template using remove_extent_t = typename remove_extent::type; template struct deref_type { using type = T; }; template struct deref_type> { using type = remove_qualifiers_t::type>; }; template struct deref_type> { using type = remove_qualifiers_t::type>; }; template struct deref_type> { using type = remove_qualifiers_t::type>; }; template struct deref_type> { using type = remove_qualifiers_t::type>; }; template struct deref_type> { using type = core::array::type>>; }; template struct deref_type> { using type = core::array::type>>; }; template using decay_t = typename deref_type>::type; template struct is_same : false_type {}; template struct is_same : true_type {}; template struct is_base_of : integral_constant {}; template struct is_class : integral_constant {}; template struct is_abstract : integral_constant {}; template struct is_polymorphic : integral_constant {}; template using is_valid_expr = true_type; #if __has_extension(is_constructible) && !((__clang_major__ == 3) && (__clang_minor__ == 5)) template using is_constructible = integral_constant; #else template decltype(void(T(declval()...)), true_type{}) test_is_constructible(int); template false_type test_is_constructible(...); template struct is_constructible : decltype(test_is_constructible(0)) {}; #endif template using is_constructible_t = typename is_constructible::type; template decltype(void(T{declval()...}), true_type{}) test_is_braces_constructible(int); template false_type test_is_braces_constructible(...); template using is_braces_constructible = decltype(test_is_braces_constructible(0)); template using is_braces_constructible_t = typename is_braces_constructible::type; #if defined(__MSVC__) template struct is_copy_constructible : integral_constant {}; template struct is_default_constructible : integral_constant {}; #else template using is_copy_constructible = is_constructible; template using is_default_constructible = is_constructible; #endif #if defined(__CLANG__) || defined(__MSVC__) template struct is_convertible : integral_constant {}; #else struct test_is_convertible__ { template static void test(T); }; template (declval()))> true_type test_is_convertible(int); template false_type test_is_convertible(...); template using is_convertible = decltype(test_is_convertible(0)); #endif template > using is_narrowed = integral_constant::value && !is_class::value && !is_same::value>; template struct is_array : false_type {}; template struct is_array : true_type {}; template true_type is_complete_impl(int); template false_type is_complete_impl(...); template struct is_complete : decltype(is_complete_impl(0)) {}; template is_base_of is_a_impl(int); template false_type is_a_impl(...); template struct is_a : decltype(is_a_impl(0)) {}; template struct is_unique_impl; template struct not_unique : false_type { using type = not_unique; }; template <> struct not_unique<> : true_type { using type = not_unique; }; template struct is_unique_impl : not_unique<> {}; template struct is_unique_impl : conditional_t, T1>::value, not_unique, is_unique_impl>, Ts...>> {}; template using is_unique = is_unique_impl; template struct unique; template struct unique, T, Ts...> : conditional_t, inherit...>>::value, unique, Ts...>, unique, Ts...>> {}; template struct unique> : type_list {}; template using unique_t = typename unique, Ts...>::type; template decltype(::boost::di::v1_1_0::aux::declval().operator()(::boost::di::v1_1_0::aux::declval()...), ::boost::di::v1_1_0::aux::true_type()) is_callable_with_impl(int); template ::boost::di::v1_1_0::aux::false_type is_callable_with_impl(...); template struct is_callable_with : decltype(is_callable_with_impl(0)) {}; struct callable_base_impl { void operator()(...) {} }; template struct callable_base : callable_base_impl, aux::conditional_t::value, T, aux::none_type> {}; template aux::false_type is_callable_impl(T*, aux::non_type* = 0); aux::true_type is_callable_impl(...); template struct is_callable : decltype(is_callable_impl((callable_base*)0)) {}; template struct function_traits; template struct function_traits { using result_type = R; using args = type_list; }; template struct function_traits { using result_type = R; using args = type_list; }; template struct function_traits { using result_type = R; using args = type_list; }; template struct function_traits { using result_type = R; using args = type_list; }; template using function_traits_t = typename function_traits::args; } namespace core { template ::type> struct bindings_impl; template struct bindings_impl { using type = typename T::deps; }; template struct bindings_impl { using type = aux::type_list; }; #if defined(__MSVC__) template struct bindings : aux::join_t::type...> {}; template using bindings_t = typename bindings::type; #else template using bindings_t = aux::join_t::type...>; #endif } namespace concepts { template struct type_ { template struct named { struct is_bound_more_than_once : aux::false_type {}; }; struct is_bound_more_than_once : aux::false_type {}; struct is_neither_a_dependency_nor_an_injector : aux::false_type {}; struct has_disallowed_qualifiers : aux::false_type {}; struct is_abstract : #if (BOOST_DI_CFG_DIAGNOSTICS_LEVEL >= 2) // clang-format off decltype( T{} ), // clang-format on #endif aux::false_type { }; template struct is_not_related_to : aux::false_type {}; }; template struct any_of : aux::false_type {}; template struct is_supported : aux::is_same::value...>, aux::bool_list<(aux::is_constructible::value && (aux::is_a::value || aux::is_a::value))...>> {}; template struct get_not_supported; template struct get_not_supported { using type = T; }; template struct get_not_supported : aux::conditional::value || aux::is_a::value, typename get_not_supported::type, T> {}; template struct is_unique; template struct unique_dependency : aux::type {}; template struct unique_dependency::value)> : aux::pair, typename T::priority> {}; template struct is_unique> : aux::is_unique::type...> {}; template struct get_is_unique_error_impl : aux::true_type {}; template struct get_is_unique_error_impl, TPriority>>> { using type = typename type_::template named::is_bound_more_than_once; }; template struct get_is_unique_error_impl, TPriority>>> { using type = typename type_::is_bound_more_than_once; }; template struct get_is_unique_error_impl> { using type = typename type_::is_bound_more_than_once; }; template struct get_is_unique_error; template struct get_is_unique_error> : get_is_unique_error_impl::type...>::type> {}; template using boundable_bindings = aux::conditional_t::value, typename get_is_unique_error>::type, typename type_::type>::is_neither_a_dependency_nor_an_injector>; template using get_any_of_error = aux::conditional_t< aux::is_same::value...>, aux::bool_list::value...>>::value, aux::true_type, any_of>; template struct is_related { static constexpr auto value = true; }; template struct is_related { static constexpr auto value = aux::is_callable::value || (aux::is_base_of::value || (aux::is_convertible::value && !aux::is_narrowed::value)); }; template struct is_abstract { static constexpr auto value = false; }; template struct is_abstract { static constexpr auto value = aux::is_abstract::value; }; auto boundable_impl(any_of<> &&) -> aux::true_type; template auto boundable_impl(any_of &&) -> aux::conditional_t>::value, decltype(boundable_impl(aux::declval>())), typename type_::has_disallowed_qualifiers>; template using boundable_impl__ = aux::conditional_t< is_related::value && aux::is_complete::value, I, T>::value, aux::conditional_t::value, T>::value, typename type_::is_abstract, aux::true_type>, typename type_::template is_not_related_to>; template auto boundable_impl(I&&, T &&) -> aux::conditional_t>::value, boundable_impl__, typename type_::has_disallowed_qualifiers>; template auto boundable_impl(I&&, T&&, aux::valid<> &&) -> aux::conditional_t::value && aux::is_complete::value, I, T>::value, aux::true_type, typename type_::template is_not_related_to>; template auto boundable_impl(I* [], T &&) -> aux::conditional_t>::value, boundable_impl__, typename type_::has_disallowed_qualifiers>; template auto boundable_impl(I[], T &&) -> aux::conditional_t>::value, boundable_impl__, typename type_::has_disallowed_qualifiers>; template auto boundable_impl(aux::type_list &&) -> boundable_bindings; template auto boundable_impl(concepts::any_of&&, T &&) -> get_any_of_error(), aux::declval()))...>; template auto boundable_impl(aux::type &&) -> typename get_is_unique_error_impl::type>::type; aux::true_type boundable_impl(...); template struct boundable__ { using type = decltype(boundable_impl(aux::declval()...)); }; template using boundable = typename boundable__::type; } namespace type_traits { struct stack {}; struct heap {}; template struct memory_traits { using type = stack; }; template struct memory_traits { using type = heap; }; template struct memory_traits { using type = typename memory_traits::type; }; template struct memory_traits> { using type = heap; }; template struct memory_traits> { using type = heap; }; template struct memory_traits> { using type = heap; }; template struct memory_traits> { using type = heap; }; template struct memory_traits::value)> { using type = heap; }; template using memory_traits_t = typename memory_traits::type; } namespace concepts { template struct scope { struct is_referable {}; struct try_create {}; struct create {}; template struct requires_ : aux::false_type {}; }; template struct provider__ { template aux::conditional_t::value, T, T*> try_get(const TMemory& = {}) const; template T* get(const TMemory& = {}) const { return nullptr; } }; template typename scope::template requires_::is_referable, typename scope<_, _>::try_create, typename scope<_, _>::create> scopable_impl(...); template auto scopable_impl(T &&) -> aux::is_valid_expr::template is_referable<_>, decltype(T::template scope<_, _>::template try_create<_, _>(provider__<_>{})), decltype(aux::declval>().template create<_, _>(provider__<_>{}))>; template struct scopable__ { using type = decltype(scopable_impl(aux::declval())); }; template using scopable = typename scopable__::type; } #if !defined(BOOST_DI_CFG_CTOR_LIMIT_SIZE) #define BOOST_DI_CFG_CTOR_LIMIT_SIZE 10 #endif namespace type_traits { template struct is_injectable : ::boost::di::v1_1_0::aux::false_type {}; template struct is_injectable> : ::boost::di::v1_1_0::aux::true_type {}; struct direct {}; struct uniform {}; template using get = T; template