1 #if COMPILATION_INSTRUCTIONS
2 (echo "#include\""$0"\"">$0x.cpp) && mpic++ -O3 -std=c++14 -Wfatal-errors -D_TEST_BOOST_MPI3_DETAIL_VALUE_TRAITS $0x.cpp -o $0x.x && time mpirun -n 1 $0x.x $@ && rm -f $0x.cpp; exit
3 #endif
4 #ifndef BOOST_MPI3_DETAIL_VALUE_TRAITS_HPP
5 #define BOOST_MPI3_DETAIL_VALUE_TRAITS_HPP
6
7 //#include "../../mpi3/detail/package_archive.hpp"
8 //#include "../../mpi3/communicator.hpp"
9
10 #include "./datatype.hpp"
11 #include "./iterator.hpp"
12 //#include "./just.hpp"
13
14 #include<iterator>
15 #include<type_traits>
16
17 namespace boost{
18 namespace mpi3{
19 namespace detail{
20
21 /*
22 template<class T>
23 struct is_memcopyable : std::integral_constant<bool, std::is_trivially_copyable<T>{}>{};
24
25 template<class T, class... Ts>
26 struct is_memcopyable<std::tuple<T, Ts...>> :
27 std::integral_constant<bool,
28 is_memcopyable<T>{} and is_memcopyable<std::tuple<Ts...>>{}
29 >
30 {};
31
32 template<class T1, class T2>
33 struct is_memcopyable<std::pair<T1, T2>> :
34 std::integral_constant<bool,
35 is_memcopyable<T1>{} and is_memcopyable<T2>{}
36 >
37 {};
38 */
39 /*
40 template<
41 class T,
42 typename = decltype(std::declval<mpi3::detail::package_oarchive&>() << std::declval<T>()),
43 typename = decltype(std::declval<mpi3::detail::package_iarchive&>() >> std::declval<T>())
44 >
45 std::true_type is_serializable_aux(T);
46 std::false_type is_serializable_aux(...);
47 */
48
49 template<class T>
50 struct is_serializable : decltype(is_serializable_aux(std::declval<T>())){};
51
52 struct value_unspecified_tag{};
53 struct nonmemcopyable_serializable_tag : value_unspecified_tag{
54 using base = value_unspecified_tag;
55 };
56 struct memcopyable_tag : value_unspecified_tag{
57 using base = value_unspecified_tag;
58 };
59 struct basic_tag : memcopyable_tag{using base = memcopyable_tag;};
60
61 //template<class V, typename = std::enable_if_t<is_memcopyable<V>{} and not is_basic<V>{}>>
62 //memcopyable_tag value_category_aux(V&&);
63 template<class V, typename = std::enable_if_t<is_basic<V>{}>>
64 basic_tag value_category_aux(V const&);
65 template<class V, std::size_t N>
66 value_unspecified_tag value_category_aux(V[N]);
67 value_unspecified_tag value_category_aux(...);
68
69
70 template<class V>
71 struct value_category{using type = decltype(value_category_aux(std::declval<V>()));};
72
73 template<class V>
74 using value_category_t = typename value_category<V>::type;
75
76 }}}
77
78 #ifdef _TEST_BOOST_MPI3_DETAIL_VALUE_TRAITS
79
80 #include "../../mpi3/environment.hpp"
81 #include "../../mpi3/main.hpp"
82
83 #include<deque>
84 #include<list>
85 #include<vector>
86
87 #include<iostream>
88
89 namespace mpi3 = boost::mpi3;
90 using std::cout;
91
92 template<class It>
f(It it,mpi3::detail::value_unspecified_tag)93 std::string f(It it, mpi3::detail::value_unspecified_tag){
94 return "memcopyable_tag";
95 };
96
97 template<class It>
f(It it,mpi3::detail::memcopyable_tag)98 std::string f(It it, mpi3::detail::memcopyable_tag){
99 return "memcopyable_tag";
100 };
101
102 template<class It>
f(It it,mpi3::detail::basic_tag const &)103 std::string f(It it, mpi3::detail::basic_tag const&){
104 return "basic_tag";
105 };
106
f(It && it)107 template<class It> std::string f(It&& it){
108 return f(
109 std::forward<It>(it),
110 typename boost::mpi3::detail::value_category<typename std::iterator_traits<It>::value_type>::type{}
111 );
112 }
113
main(int,char * [],mpi3::communicator)114 int mpi3::main(int, char*[], mpi3::communicator){
115
116 {
117 std::list<std::tuple<double, double>> l1;
118 // assert( f(begin(l1)) == "memcopyable_tag" );
119 // std::list<double> l2;
120 // assert( f(begin(l2)) == "basic_tag" );
121 // static_assert(std::is_trivially_copyable<std::complex<double>>{}, "complex is not trivially copyable?");
122 // assert( f(nullptr, mpi3::detail::value_category_t<std::tuple<double, double>>{}) == "memcopyable_tag" );
123 // assert( f(nullptr, mpi3::detail::value_category_t<std::string>{}) == "memcopyable_tag" );
124 }
125
126 return 0;
127 }
128 #endif
129 #endif
130
131