Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/hof/is_unpackable.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*=============================================================================
0002     Copyright (c) 2016 Paul Fultz II
0003     is_unpackable.hpp
0004     Distributed under the Boost Software License, Version 1.0. (See accompanying
0005     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 ==============================================================================*/
0007 
0008 #ifndef BOOST_HOF_GUARD_IS_UNPACKABLE_HPP
0009 #define BOOST_HOF_GUARD_IS_UNPACKABLE_HPP
0010 
0011 /// is_unpackable
0012 /// =============
0013 /// 
0014 /// This is a trait that can be used to detect whether the type can be called
0015 /// with `unpack`.
0016 /// 
0017 /// Synopsis
0018 /// --------
0019 /// 
0020 ///     template<class T>
0021 ///     struct is_unpackable;
0022 /// 
0023 /// Example
0024 /// -------
0025 /// 
0026 ///     #include <boost/hof.hpp>
0027 ///     #include <cassert>
0028 /// 
0029 ///     int main() {
0030 ///         static_assert(boost::hof::is_unpackable<std::tuple<int>>::value, "Failed");
0031 ///     }
0032 /// 
0033 
0034 #include <boost/hof/unpack_sequence.hpp>
0035 #include <boost/hof/is_invocable.hpp>
0036 #include <boost/hof/always.hpp>
0037 #include <boost/hof/detail/static_const_var.hpp>
0038 #include <boost/hof/detail/unpack_tuple.hpp>
0039 
0040 namespace boost { namespace hof {
0041 
0042 namespace detail {
0043 
0044 struct unpack_impl_f
0045 {
0046     template<class F, class Sequence>
0047     constexpr auto operator()(F&& f, Sequence&& s) const BOOST_HOF_RETURNS
0048     (
0049         boost::hof::unpack_sequence<typename std::remove_cv<typename std::remove_reference<Sequence>::type>::type>::
0050                 apply(BOOST_HOF_FORWARD(F)(f), BOOST_HOF_FORWARD(Sequence)(s))
0051     );
0052 };
0053 
0054 BOOST_HOF_DECLARE_STATIC_VAR(unpack_impl, unpack_impl_f);
0055 
0056 #if BOOST_HOF_CHECK_UNPACK_SEQUENCE
0057 struct private_unpack_type {};
0058 template<class Sequence>
0059 struct unpack_impl_result
0060 {
0061     static_assert(boost::hof::is_invocable<unpack_impl_f, decltype(boost::hof::always(private_unpack_type())), Sequence>::value,
0062         "Unpack is invalid for this sequence. The function used to unpack this sequence is not callable."
0063     );
0064     typedef decltype(boost::hof::detail::unpack_impl(boost::hof::always(private_unpack_type()), std::declval<Sequence>())) type;
0065 };
0066 
0067 template<class Sequence>
0068 struct is_proper_sequence
0069 : std::is_same<
0070     private_unpack_type, 
0071     typename unpack_impl_result<Sequence>::type
0072 >
0073 {};
0074 #endif
0075 template<class Sequence, class=void>
0076 struct is_unpackable_impl
0077 : std::true_type
0078 {
0079 #if BOOST_HOF_CHECK_UNPACK_SEQUENCE
0080     static_assert(is_proper_sequence<Sequence>::value,
0081         "Unpack is invalid for this sequence. The function used to unpack this sequence does not invoke the function."
0082     );
0083 #endif
0084 };
0085 
0086 template<class Sequence>
0087 struct is_unpackable_impl<Sequence, typename detail::holder<
0088     typename unpack_sequence<Sequence>::not_unpackable
0089 >::type>
0090 : std::false_type
0091 {};
0092 
0093 }
0094 
0095 template<class Sequence>
0096 struct is_unpackable
0097 : detail::is_unpackable_impl<
0098     typename std::remove_cv<typename std::remove_reference<Sequence>::type>::type
0099 >
0100 {
0101 #if BOOST_HOF_CHECK_UNPACK_SEQUENCE
0102 typedef detail::is_unpackable_impl<
0103     typename std::remove_cv<typename std::remove_reference<Sequence>::type>::type
0104 > base;
0105 
0106 typedef std::conditional<base::value, detail::is_proper_sequence<Sequence>, std::true_type> check;
0107 static_assert(check::type::value,
0108     "Unpack is invalid for this sequence. The function used to unpack this sequence does not invoke the function."
0109 );
0110 #endif
0111 };
0112 
0113 }} // namespace boost::hof
0114 
0115 #endif