• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*!
2 @file
3 Adapts `std::vector` for use with Hana.
4 
5 @copyright Louis Dionne 2013-2017
6 @copyright Gonzalo Brito Gadeschi 2015
7 Distributed under the Boost Software License, Version 1.0.
8 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
9  */
10 
11 #ifndef BOOST_HANA_EXT_STD_VECTOR_HPP
12 #define BOOST_HANA_EXT_STD_VECTOR_HPP
13 
14 #include <boost/hana/config.hpp>
15 #include <boost/hana/equal.hpp>
16 #include <boost/hana/fwd/core/tag_of.hpp>
17 #include <boost/hana/less.hpp>
18 
19 #include <algorithm>
20 #include <iterator>
21 #include <memory>
22 #include <type_traits>
23 #include <utility>
24 #include <vector>
25 
26 
27 BOOST_HANA_NAMESPACE_BEGIN
28     namespace ext { namespace std { struct vector_tag; }}
29 
30     template <typename T, typename Allocator>
31     struct tag_of<std::vector<T, Allocator>> {
32         using type = ext::std::vector_tag;
33     };
34 
35     //////////////////////////////////////////////////////////////////////////
36     // Comparable
37     //////////////////////////////////////////////////////////////////////////
38     template <>
39     struct equal_impl<ext::std::vector_tag, ext::std::vector_tag> {
40         template <typename T1, typename A1, typename T2, typename A2>
applyequal_impl41         static bool apply(std::vector<T1, A1> const& v1,
42                           std::vector<T2, A2> const& v2)
43         {
44             return std::equal(begin(v1), end(v1),
45                               begin(v2), end(v2),
46                               hana::equal);
47         }
48     };
49 
50     //////////////////////////////////////////////////////////////////////////
51     // Orderable
52     //////////////////////////////////////////////////////////////////////////
53     template <>
54     struct less_impl<ext::std::vector_tag, ext::std::vector_tag> {
55         template <typename T1, typename A1, typename T2, typename A2>
applyless_impl56         static bool apply(std::vector<T1, A1> const& v1,
57                           std::vector<T2, A2> const& v2)
58         {
59             return std::lexicographical_compare(begin(v1), end(v1),
60                                                 begin(v2), end(v2),
61                                                 hana::less);
62         }
63     };
64 
65 #if 0
66     //////////////////////////////////////////////////////////////////////////
67     // Functor
68     //////////////////////////////////////////////////////////////////////////
69     template <>
70     struct transform_impl<ext::std::vector_tag> {
71         template <typename V, typename F>
72         static auto apply(V&& v, F&& f) {
73             using U = std::remove_cv_t<std::remove_reference_t<
74                 decltype(f(*v.begin()))
75             >>;
76             using Alloc = typename std::remove_reference_t<V>::allocator_type;
77             using NewAlloc = typename std::allocator_traits<Alloc>::
78                              template rebind_alloc<U>;
79             std::vector<U, NewAlloc> result; result.reserve(v.size());
80 
81             std::transform(begin(v), end(v),
82                            std::back_inserter(result), std::forward<F>(f));
83             return result;
84         }
85 
86         template <typename T, typename Alloc, typename F>
87         static auto apply(std::vector<T, Alloc>&& v, F&& f)
88             -> std::enable_if_t<
89                 std::is_same<
90                     T,
91                     std::remove_cv_t<std::remove_reference_t<
92                         decltype(f(*v.begin()))
93                     >>
94                 >{}
95                 , std::vector<T, Alloc>
96             >
97         {
98             // If we receive a rvalue and the function returns elements of
99             // the same type, we modify the vector in-place instead of
100             // returning a new one.
101             std::transform(std::make_move_iterator(begin(v)),
102                            std::make_move_iterator(end(v)),
103                            begin(v), std::forward<F>(f));
104             return std::move(v);
105         }
106     };
107 #endif
108 BOOST_HANA_NAMESPACE_END
109 
110 #endif // !BOOST_HANA_EXT_STD_VECTOR_HPP
111