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