deque.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*!
  2. @file
  3. Adapts `boost::fusion::deque` for use with Hana.
  4. @copyright Louis Dionne 2013-2017
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_EXT_BOOST_FUSION_DEQUE_HPP
  9. #define BOOST_HANA_EXT_BOOST_FUSION_DEQUE_HPP
  10. #include <boost/hana/at.hpp>
  11. #include <boost/hana/core/when.hpp>
  12. #include <boost/hana/config.hpp>
  13. #include <boost/hana/ext/boost/fusion/detail/common.hpp>
  14. #include <boost/hana/fwd/core/make.hpp>
  15. #include <boost/hana/fwd/core/tag_of.hpp>
  16. #include <boost/hana/fwd/drop_front.hpp>
  17. #include <boost/hana/length.hpp>
  18. #include <boost/fusion/container/deque.hpp>
  19. #include <boost/fusion/container/generation/make_deque.hpp>
  20. #include <boost/fusion/support/tag_of.hpp>
  21. #include <cstddef>
  22. #include <type_traits>
  23. #include <utility>
  24. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  25. namespace boost { namespace fusion {
  26. //! @ingroup group-ext-fusion
  27. //! Adapter for Boost.Fusion deques.
  28. //!
  29. //!
  30. //! Modeled concepts
  31. //! ----------------
  32. //! A Fusion deque is a model of the `Sequence` concept, and all the
  33. //! concepts it refines. That makes it essentially the same as a Hana
  34. //! tuple, although the complexity of some operations might differ from
  35. //! that of a tuple.
  36. //!
  37. //! @include example/ext/boost/fusion/deque.cpp
  38. template <typename ...T>
  39. struct deque { };
  40. }}
  41. #endif
  42. BOOST_HANA_NAMESPACE_BEGIN
  43. namespace ext { namespace boost { namespace fusion {
  44. struct deque_tag;
  45. }}}
  46. template <typename T>
  47. struct tag_of<T, when<
  48. std::is_same<
  49. typename ::boost::fusion::traits::tag_of<T>::type,
  50. ::boost::fusion::traits::tag_of<
  51. ::boost::fusion::deque<>
  52. >::type
  53. >::value
  54. >> {
  55. using type = ext::boost::fusion::deque_tag;
  56. };
  57. namespace detail {
  58. template <>
  59. struct is_fusion_sequence<ext::boost::fusion::deque_tag> {
  60. static constexpr bool value = true;
  61. };
  62. }
  63. //////////////////////////////////////////////////////////////////////////
  64. // Iterable (the rest is in detail/common.hpp)
  65. //////////////////////////////////////////////////////////////////////////
  66. template <>
  67. struct drop_front_impl<ext::boost::fusion::deque_tag> {
  68. template <std::size_t n, typename Xs, std::size_t ...i>
  69. static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
  70. return hana::make<ext::boost::fusion::deque_tag>(
  71. hana::at_c<n + i>(static_cast<Xs&&>(xs))...
  72. );
  73. }
  74. template <typename Xs, typename N>
  75. static constexpr auto apply(Xs&& xs, N const&) {
  76. constexpr std::size_t n = N::value;
  77. constexpr std::size_t len = decltype(hana::length(xs))::value;
  78. return drop_front_helper<n>(static_cast<Xs&&>(xs),
  79. std::make_index_sequence<(n < len ? len - n : 0)>{});
  80. }
  81. };
  82. //////////////////////////////////////////////////////////////////////////
  83. // Sequence
  84. //////////////////////////////////////////////////////////////////////////
  85. template <>
  86. struct make_impl<ext::boost::fusion::deque_tag> {
  87. template <typename ...Xs>
  88. static constexpr auto apply(Xs&& ...xs) {
  89. return ::boost::fusion::make_deque(static_cast<Xs&&>(xs)...);
  90. }
  91. };
  92. BOOST_HANA_NAMESPACE_END
  93. #endif // !BOOST_HANA_EXT_BOOST_FUSION_DEQUE_HPP