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