1 // Copyright 2015, Tobias Hermann and the FunctionalPlus contributors.
2 // https://github.com/Dobiasd/FunctionalPlus
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 //  http://www.boost.org/LICENSE_1_0.txt)
6 
7 #pragma once
8 
9 #include <fplus/internal/function_traits_asserts.hpp>
10 
11 namespace fplus
12 {
13 namespace internal
14 {
15 struct apply_to_pair_tag
16 {
17 };
18 
19 struct zip_with_tag
20 {
21 };
22 
23 struct zip_with_3_tag
24 {
25 };
26 
27 struct transform_fst_tag
28 {
29 };
30 
31 struct transform_snd_tag
32 {
33 };
34 
35 struct inner_product_with_tag
36 {
37 };
38 
39 template <typename F, typename X, typename Y>
40 struct function_traits_asserts<apply_to_pair_tag, F, X, Y>
41 {
42     static_assert(utils::function_traits<F>::arity == 2,
43         "Function must take two parameters.");
44     typedef typename utils::function_traits<F>::template arg<0>::type FIn0;
45     typedef typename utils::function_traits<F>::template arg<1>::type FIn1;
46     static_assert(std::is_convertible<X, FIn0>::value,
47         "Function does not take pair.first type as first Parameter.");
48     static_assert(std::is_convertible<Y, FIn1>::value,
49         "Function does not take pair.second type as second Parameter.");
50 };
51 
52 template <typename F, typename X, typename Y>
53 struct function_traits_asserts<zip_with_tag, F, X, Y>
54 {
55     static_assert(utils::function_traits<F>::arity == 2,
56         "Function must take two parameters.");
57     typedef typename utils::function_traits<F>::template arg<0>::type FIn0;
58     typedef typename utils::function_traits<F>::template arg<1>::type FIn1;
59     static_assert(std::is_convertible<X, FIn0>::value,
60         "Function does not take elements from first Container as first Parameter.");
61     static_assert(std::is_convertible<Y, FIn1>::value,
62         "Function does not take elements from second Container as second Parameter.");
63 };
64 
65 template <typename F, typename X, typename Y, typename Z>
66 struct function_traits_asserts<zip_with_3_tag, F, X, Y, Z>
67 {
68     static_assert(utils::function_traits<F>::arity == 3,
69         "Function must take two parameters.");
70     typedef typename utils::function_traits<F>::template arg<0>::type FIn0;
71     typedef typename utils::function_traits<F>::template arg<1>::type FIn1;
72     typedef typename utils::function_traits<F>::template arg<2>::type FIn2;
73     static_assert(std::is_convertible<X, FIn0>::value,
74         "Function does not take elements from first Container as first Parameter.");
75     static_assert(std::is_convertible<Y, FIn1>::value,
76         "Function does not take elements from second Container as second Parameter.");
77     static_assert(std::is_convertible<Z, FIn2>::value,
78         "Function does not take elements from third Container as third Parameter.");
79 };
80 
81 template <typename F, typename X>
82 struct function_traits_asserts<transform_fst_tag, F, X>
83 {
84     static_assert(utils::function_traits<F>::arity == 1,
85         "Function must take one parameter.");
86     typedef typename utils::function_traits<F>::template arg<0>::type FIn0;
87     static_assert(std::is_convertible<X, FIn0>::value,
88         "Function does not take pair.first type as first Parameter.");
89 };
90 
91 template <typename F, typename X>
92 struct function_traits_asserts<transform_snd_tag, F, X>
93 {
94     static_assert(utils::function_traits<F>::arity == 1,
95         "Function must take one parameter.");
96     typedef typename utils::function_traits<F>::template arg<0>::type FIn0;
97     static_assert(std::is_convertible<X, FIn0>::value,
98         "Function does not take pair.second type as first Parameter.");
99 };
100 
101 template <typename F, typename X, typename Y>
102 struct function_traits_asserts<inner_product_with_tag, F, X, Y>
103 {
104     static_assert(utils::function_traits<F>::arity == 2,
105         "Function must take two parameters.");
106     typedef typename utils::function_traits<F>::template arg<0>::type FIn0;
107     typedef typename utils::function_traits<F>::template arg<1>::type FIn1;
108     static_assert(std::is_convertible<X, FIn0>::value,
109         "Function does not take elements from first Container as first Parameter.");
110     static_assert(std::is_convertible<Y, FIn1>::value,
111         "Function does not take elements from second Container as second Parameter.");
112 };
113 }
114 }
115