1 /* Copyright 2017-2018 Fizyr B.V. - https://fizyr.com
2  *
3  * Redistribution and use in source and binary forms, with or without modification,
4  * are permitted provided that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain the above copyright notice,
7  *    this list of conditions and the following disclaimer.
8  *
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *
13  * 3. Neither the name of the copyright holder nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software without
15  *    specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #pragma once
30 #include "../traits.hpp"
31 
32 #include <vector>
33 #include <type_traits>
34 
35 namespace estd {
36 
37 /// Convert a vector<F> to vector<T>.
38 template<typename F, typename T, typename Tag>
39 struct conversion<std::vector<F>, std::vector<T>, Tag> {
40 	using From = std::vector<F>;
41 	using To   = std::vector<T>;
42 
43 	static constexpr bool possible = can_convert<F, T, Tag>;
44 
performestd::conversion45 	static To perform(From const & from) {
46 		static_assert(possible, "no conversion available for F and T");
47 		To result;
48 		for (F const & elem : from) result.push_back(convert<T, Tag>(elem));
49 		return result;
50 	}
51 
performestd::conversion52 	static To perform(From && from) {
53 		static_assert(possible, "no conversion available for F and T");
54 		To result;
55 		for (F & elem : from) result.push_back(convert<T, Tag>(std::move(elem)));
56 		return result;
57 	}
58 };
59 
60 /// Parse a vector<F> to result<vector<T>, E>.
61 template<typename F, typename T, typename E, typename Tag>
62 struct conversion<std::vector<F>, result<std::vector<T>, E>, Tag> {
63 	using From   = std::vector<F>;
64 	using Raw    = std::vector<T>;
65 	using To     = result<Raw, E>;
66 
67 	static constexpr bool possible = can_parse<F, T, E, Tag>;
68 
convertestd::conversion69 	static To convert(From const & from) {
70 		static_assert(possible, "no conversion available for F and result<T, E>");
71 		Raw result;
72 		result.reserve(from.size());
73 		for (F const & elem : from) {
74 			estd::result<T, E> converted = parse<T, E>(elem);
75 			if (!converted) return converted.error_unchecked();
76 			result.push_back(std::move(*converted));
77 		}
78 		return result;
79 	}
80 
convertestd::conversion81 	static To convert(From && from) {
82 		static_assert(possible, "no conversion available for F and result<T, E>");
83 		Raw result;
84 		result.reserve(from.size());
85 		for (F & elem : from) {
86 			estd::result<T, E> converted = parse<T, E>(std::move(elem));
87 			if (!converted) return converted.error_unchecked();
88 			result.push_back(std::move(*converted));
89 		}
90 		return result;
91 	}
92 };
93 
94 }
95