1 /* Copyright 2009-2016 Francesco Biscani (bluescarni@gmail.com)
2 
3 This file is part of the Piranha library.
4 
5 The Piranha library is free software; you can redistribute it and/or modify
6 it under the terms of either:
7 
8   * the GNU Lesser General Public License as published by the Free
9     Software Foundation; either version 3 of the License, or (at your
10     option) any later version.
11 
12 or
13 
14   * the GNU General Public License as published by the Free Software
15     Foundation; either version 3 of the License, or (at your option) any
16     later version.
17 
18 or both in parallel, as here.
19 
20 The Piranha library is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23 for more details.
24 
25 You should have received copies of the GNU General Public License and the
26 GNU Lesser General Public License along with the Piranha library.  If not,
27 see https://www.gnu.org/licenses/. */
28 
29 #include "../src/monomial.hpp"
30 
31 #define BOOST_TEST_MODULE monomial_02_test
32 #include <boost/test/included/unit_test.hpp>
33 
34 #include <boost/algorithm/string/predicate.hpp>
35 #include <cstddef>
36 #include <functional>
37 #include <initializer_list>
38 #include <iostream>
39 #include <random>
40 #include <sstream>
41 #include <stdexcept>
42 #include <string>
43 #include <tuple>
44 #include <type_traits>
45 #include <vector>
46 
47 #include "../src/config.hpp"
48 #include "../src/init.hpp"
49 #include "../src/is_key.hpp"
50 #include "../src/mp_integer.hpp"
51 #include "../src/mp_rational.hpp"
52 #include "../src/s11n.hpp"
53 #include "../src/symbol.hpp"
54 #include "../src/symbol_set.hpp"
55 #include "../src/type_traits.hpp"
56 
57 using namespace piranha;
58 
59 using expo_types = std::tuple<signed char, int, integer, rational>;
60 using size_types = std::tuple<std::integral_constant<std::size_t, 0u>, std::integral_constant<std::size_t, 1u>,
61                               std::integral_constant<std::size_t, 5u>, std::integral_constant<std::size_t, 10u>>;
62 
63 static const int ntrials = 100;
64 
65 static std::mt19937 rng;
66 
67 // This is missing the s11n methods.
68 struct fake_int_01 {
69     fake_int_01();
70     explicit fake_int_01(int);
71     fake_int_01(const fake_int_01 &);
72     fake_int_01(fake_int_01 &&) noexcept;
73     fake_int_01 &operator=(const fake_int_01 &);
74     fake_int_01 &operator=(fake_int_01 &&) noexcept;
75     ~fake_int_01();
76     bool operator==(const fake_int_01 &) const;
77     bool operator!=(const fake_int_01 &) const;
78     bool operator<(const fake_int_01 &) const;
79     fake_int_01 operator+(const fake_int_01 &) const;
80     fake_int_01 &operator+=(const fake_int_01 &);
81     fake_int_01 operator-(const fake_int_01 &) const;
82     fake_int_01 &operator-=(const fake_int_01 &);
83     friend std::ostream &operator<<(std::ostream &, const fake_int_01 &);
84 };
85 
86 namespace std
87 {
88 
89 template <>
90 struct hash<fake_int_01> {
91     typedef size_t result_type;
92     typedef fake_int_01 argument_type;
93     result_type operator()(const argument_type &) const;
94 };
95 }
96 
97 namespace piranha
98 {
99 
100 namespace math
101 {
102 
103 template <>
104 struct negate_impl<fake_int_01> {
105     void operator()(fake_int_01 &) const;
106 };
107 }
108 }
109 
110 template <typename OArchive, typename IArchive, typename Monomial>
boost_round_trip_monomial(const Monomial & m,const symbol_set & s)111 static inline Monomial boost_round_trip_monomial(const Monomial &m, const symbol_set &s)
112 {
113     using w_type = boost_s11n_key_wrapper<Monomial>;
114     std::stringstream ss;
115     {
116         OArchive oa(ss);
117         boost_save(oa, w_type{m, s});
118     }
119     Monomial n;
120     {
121         IArchive ia(ss);
122         w_type w{n, s};
123         boost_load(ia, w);
124     }
125     return n;
126 }
127 
128 struct boost_s11n_tester {
129     template <typename T>
130     struct runner {
131         template <typename U>
operator ()boost_s11n_tester::runner132         void operator()(const U &) const
133         {
134             using monomial_type = monomial<T, U>;
135             using w_type = boost_s11n_key_wrapper<monomial_type>;
136             // Test the type traits.
137             BOOST_CHECK((has_boost_save<boost::archive::binary_oarchive, w_type>::value));
138             BOOST_CHECK((has_boost_save<boost::archive::binary_oarchive, w_type &>::value));
139             BOOST_CHECK((has_boost_save<boost::archive::binary_oarchive, const w_type &>::value));
140             BOOST_CHECK((has_boost_save<boost::archive::binary_oarchive, const w_type>::value));
141             BOOST_CHECK((has_boost_load<boost::archive::binary_iarchive, w_type>::value));
142             BOOST_CHECK((has_boost_load<boost::archive::binary_iarchive, w_type &>::value));
143             BOOST_CHECK((has_boost_load<boost::archive::binary_iarchive, w_type &&>::value));
144             BOOST_CHECK((!has_boost_load<boost::archive::binary_iarchive, const w_type &>::value));
145             BOOST_CHECK((!has_boost_load<boost::archive::binary_iarchive, const w_type>::value));
146             BOOST_CHECK((has_boost_save<boost::archive::binary_oarchive &, w_type>::value));
147             BOOST_CHECK((has_boost_save<boost::archive::binary_oarchive &, w_type &>::value));
148             BOOST_CHECK((has_boost_save<boost::archive::binary_oarchive &, w_type &&>::value));
149             BOOST_CHECK((has_boost_load<boost::archive::binary_iarchive &, w_type>::value));
150             BOOST_CHECK((!has_boost_save<boost::archive::binary_iarchive, w_type>::value));
151             BOOST_CHECK((!has_boost_load<boost::archive::binary_oarchive, w_type>::value));
152             BOOST_CHECK((!has_boost_save<const boost::archive::binary_oarchive, w_type>::value));
153             BOOST_CHECK((!has_boost_load<const boost::archive::binary_iarchive, w_type>::value));
154             BOOST_CHECK((!has_boost_save<const boost::archive::binary_oarchive &, w_type>::value));
155             BOOST_CHECK((!has_boost_load<const boost::archive::binary_iarchive &, w_type>::value));
156             BOOST_CHECK((!has_boost_save<int, w_type>::value));
157             BOOST_CHECK((!has_boost_load<int, w_type>::value));
158             // Check exceptions.
159             symbol_set s{symbol{"a"}};
160             monomial_type m;
161             std::stringstream ss;
162             {
163                 boost::archive::text_oarchive oa(ss);
164                 BOOST_CHECK_EXCEPTION(
165                     boost_save(oa, w_type{m, s}), std::invalid_argument, [](const std::invalid_argument &ia) {
166                         return boost::contains(
167                             ia.what(),
168                             "incompatible symbol set in monomial serialization: the reference "
169                             "symbol set has a size of 1, while the monomial being serialized has a size of 0");
170                     });
171             }
172             ss.str("");
173             ss.clear();
174             m = monomial_type{T(1)};
175             {
176                 boost::archive::text_oarchive oa(ss);
177                 boost_save(oa, w_type{m, s});
178             }
179             {
180                 boost::archive::text_iarchive ia(ss);
181                 symbol_set s2;
182                 w_type w{m, s2};
183                 BOOST_CHECK_EXCEPTION(boost_load(ia, w), std::invalid_argument, [](const std::invalid_argument &iae) {
184                     return boost::contains(
185                         iae.what(),
186                         "incompatible symbol set in monomial serialization: the reference "
187                         "symbol set has a size of 0, while the monomial being deserialized has a size of 1");
188                 });
189             }
190             // A few simple tests.
191             m = monomial_type{};
192             auto n = boost_round_trip_monomial<boost::archive::binary_oarchive, boost::archive::binary_iarchive>(
193                 m, symbol_set{});
194             BOOST_CHECK(n == m);
195             n = boost_round_trip_monomial<boost::archive::text_oarchive, boost::archive::text_iarchive>(m,
196                                                                                                         symbol_set{});
197             BOOST_CHECK(n == m);
198             std::vector<T> vexpo = {T(1), T(2), T(3)};
199             m = monomial_type(vexpo.begin(), vexpo.end());
200             n = boost_round_trip_monomial<boost::archive::binary_oarchive, boost::archive::binary_iarchive>(
201                 m, symbol_set{symbol{"a"}, symbol{"b"}, symbol{"c"}});
202             BOOST_CHECK(n == m);
203             n = boost_round_trip_monomial<boost::archive::text_oarchive, boost::archive::text_iarchive>(
204                 m, symbol_set{symbol{"a"}, symbol{"b"}, symbol{"c"}});
205             BOOST_CHECK(n == m);
206             // Random testing.
207             random_test<U>();
208         }
209         template <typename U, typename V = T, typename std::enable_if<std::is_same<V, integer>::value, int>::type = 0>
random_testboost_s11n_tester::runner210         void random_test() const
211         {
212             using monomial_type = monomial<T, U>;
213             using size_type = typename monomial_type::size_type;
214             std::uniform_int_distribution<size_type> sdist(0u, 10u);
215             std::uniform_int_distribution<int> edist(-10, 10);
216             const std::vector<std::string> vs = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
217             for (auto i = 0; i < ntrials; ++i) {
218                 const auto size = sdist(rng);
219                 std::vector<T> tmp;
220                 for (size_type j = 0; j < size; ++j) {
221                     tmp.emplace_back(edist(rng));
222                 }
223                 monomial_type m(tmp.begin(), tmp.end());
224                 symbol_set ss(vs.begin(), vs.begin() + size);
225                 BOOST_CHECK(
226                     (m == boost_round_trip_monomial<boost::archive::text_oarchive, boost::archive::text_iarchive>(m,
227                                                                                                                   ss)));
228                 BOOST_CHECK(
229                     (m == boost_round_trip_monomial<boost::archive::binary_oarchive, boost::archive::binary_iarchive>(
230                               m, ss)));
231             }
232         }
233         template <typename U, typename V = T, typename std::enable_if<std::is_same<V, rational>::value, int>::type = 0>
random_testboost_s11n_tester::runner234         void random_test() const
235         {
236             using monomial_type = monomial<T, U>;
237             using size_type = typename monomial_type::size_type;
238             std::uniform_int_distribution<size_type> sdist(0u, 10u);
239             std::uniform_int_distribution<int> edist(-10, 10);
240             const std::vector<std::string> vs = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
241             for (auto i = 0; i < ntrials; ++i) {
242                 const auto size = sdist(rng);
243                 std::vector<T> tmp;
244                 for (size_type j = 0; j < size; ++j) {
245                     int num = edist(rng), den = edist(rng);
246                     if (!den) {
247                         den = 1;
248                     }
249                     tmp.emplace_back(num, den);
250                 }
251                 monomial_type m(tmp.begin(), tmp.end());
252                 symbol_set ss(vs.begin(), vs.begin() + size);
253                 BOOST_CHECK(
254                     (m == boost_round_trip_monomial<boost::archive::text_oarchive, boost::archive::text_iarchive>(m,
255                                                                                                                   ss)));
256                 BOOST_CHECK(
257                     (m == boost_round_trip_monomial<boost::archive::binary_oarchive, boost::archive::binary_iarchive>(
258                               m, ss)));
259             }
260         }
261         template <typename U, typename V = T, typename std::enable_if<std::is_integral<V>::value, int>::type = 0>
random_testboost_s11n_tester::runner262         void random_test() const
263         {
264             using monomial_type = monomial<T, U>;
265             using size_type = typename monomial_type::size_type;
266             std::uniform_int_distribution<size_type> sdist(0u, 10u);
267             std::uniform_int_distribution<T> edist(-10, 10);
268             const std::vector<std::string> vs = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
269             for (auto i = 0; i < ntrials; ++i) {
270                 const auto size = sdist(rng);
271                 std::vector<T> tmp;
272                 for (size_type j = 0; j < size; ++j) {
273                     tmp.push_back(edist(rng));
274                 }
275                 monomial_type m(tmp.begin(), tmp.end());
276                 symbol_set ss(vs.begin(), vs.begin() + size);
277                 BOOST_CHECK(
278                     (m == boost_round_trip_monomial<boost::archive::text_oarchive, boost::archive::text_iarchive>(m,
279                                                                                                                   ss)));
280                 BOOST_CHECK(
281                     (m == boost_round_trip_monomial<boost::archive::binary_oarchive, boost::archive::binary_iarchive>(
282                               m, ss)));
283             }
284         }
285     };
286     template <typename T>
operator ()boost_s11n_tester287     void operator()(const T &) const
288     {
289         tuple_for_each(size_types{}, runner<T>());
290     }
291 };
292 
BOOST_AUTO_TEST_CASE(monomial_boost_s11n_test)293 BOOST_AUTO_TEST_CASE(monomial_boost_s11n_test)
294 {
295     init();
296     tuple_for_each(expo_types{}, boost_s11n_tester());
297     BOOST_CHECK((is_key<monomial<fake_int_01>>::value));
298     BOOST_CHECK(
299         (!has_boost_save<boost::archive::binary_oarchive, boost_s11n_key_wrapper<monomial<fake_int_01>>>::value));
300     BOOST_CHECK(
301         (!has_boost_load<boost::archive::binary_iarchive, boost_s11n_key_wrapper<monomial<fake_int_01>>>::value));
302 }
303 
304 #if defined(PIRANHA_WITH_MSGPACK)
305 
306 #include <algorithm>
307 #include <atomic>
308 #include <iterator>
309 #include <thread>
310 
311 using msgpack::sbuffer;
312 using msgpack::packer;
313 
314 template <typename T>
315 using sw = msgpack_stream_wrapper<T>;
316 
317 template <typename Monomial>
msgpack_round_trip_monomial(const Monomial & m,const symbol_set & s,msgpack_format f)318 static inline Monomial msgpack_round_trip_monomial(const Monomial &m, const symbol_set &s, msgpack_format f)
319 {
320     sbuffer sbuf;
321     packer<sbuffer> p(sbuf);
322     m.msgpack_pack(p, f, s);
323     auto oh = msgpack::unpack(sbuf.data(), sbuf.size());
324     Monomial n;
325     n.msgpack_convert(oh.get(), f, s);
326     return n;
327 }
328 
329 template <typename Monomial>
msgpack_round_trip_monomial_ss(const Monomial & m,const symbol_set & s,msgpack_format f)330 static inline Monomial msgpack_round_trip_monomial_ss(const Monomial &m, const symbol_set &s, msgpack_format f)
331 {
332     sw<std::stringstream> ss;
333     packer<sw<std::stringstream>> p(ss);
334     m.msgpack_pack(p, f, s);
335     std::vector<char> vchar;
336     std::copy(std::istreambuf_iterator<char>(ss), std::istreambuf_iterator<char>(), std::back_inserter(vchar));
337     auto oh = msgpack::unpack(vchar.data(), static_cast<std::size_t>(vchar.size()));
338     Monomial n;
339     n.msgpack_convert(oh.get(), f, s);
340     return n;
341 }
342 
343 struct msgpack_tester {
344     template <typename T>
345     struct runner {
346         template <typename U>
operator ()msgpack_tester::runner347         void operator()(const U &) const
348         {
349             using monomial_type = monomial<T, U>;
350             BOOST_CHECK((key_has_msgpack_pack<msgpack::sbuffer, monomial_type>::value));
351             BOOST_CHECK((key_has_msgpack_pack<std::ostringstream, monomial_type>::value));
352             BOOST_CHECK((key_has_msgpack_pack<std::ostringstream, monomial_type &>::value));
353             BOOST_CHECK((key_has_msgpack_pack<std::ostringstream, const monomial_type &>::value));
354             BOOST_CHECK((key_has_msgpack_pack<std::ostringstream, const monomial_type>::value));
355             BOOST_CHECK((key_has_msgpack_pack<sw<std::ostringstream>, monomial_type>::value));
356             BOOST_CHECK((!key_has_msgpack_pack<msgpack::sbuffer &, monomial_type>::value));
357             BOOST_CHECK((!key_has_msgpack_pack<int, monomial_type>::value));
358             BOOST_CHECK((!key_has_msgpack_pack<const std::ostringstream, monomial_type>::value));
359             BOOST_CHECK((!key_has_msgpack_pack<const std::ostringstream &&, monomial_type>::value));
360             BOOST_CHECK((!key_has_msgpack_pack<std::ostringstream &&, monomial_type>::value));
361             BOOST_CHECK((key_has_msgpack_convert<monomial_type>::value));
362             BOOST_CHECK((key_has_msgpack_convert<monomial_type &>::value));
363             BOOST_CHECK((key_has_msgpack_convert<monomial_type &&>::value));
364             BOOST_CHECK((!key_has_msgpack_convert<const monomial_type &>::value));
365             BOOST_CHECK((!key_has_msgpack_convert<const monomial_type>::value));
366             // Some simple checks.
367             for (auto f : {msgpack_format::portable, msgpack_format::binary}) {
368                 BOOST_CHECK((msgpack_round_trip_monomial(monomial_type{}, symbol_set{}, f) == monomial_type{}));
369                 BOOST_CHECK((msgpack_round_trip_monomial_ss(monomial_type{}, symbol_set{}, f) == monomial_type{}));
370                 monomial_type m{T(1), T(2)};
371                 symbol_set s{symbol{"a"}, symbol{"b"}};
372                 BOOST_CHECK((msgpack_round_trip_monomial(m, s, f) == m));
373                 BOOST_CHECK((msgpack_round_trip_monomial_ss(m, s, f) == m));
374                 // Test exceptions.
375                 sbuffer sbuf;
376                 packer<sbuffer> p(sbuf);
377                 BOOST_CHECK_EXCEPTION(
378                     m.msgpack_pack(p, f, symbol_set{}), std::invalid_argument, [](const std::invalid_argument &ia) {
379                         return boost::contains(
380                             ia.what(),
381                             "incompatible symbol set in monomial serialization: the reference "
382                             "symbol set has a size of 0, while the monomial being serialized has a size of 2");
383                     });
384                 m.msgpack_pack(p, f, s);
385                 auto oh = msgpack::unpack(sbuf.data(), sbuf.size());
386                 BOOST_CHECK_EXCEPTION(
387                     m.msgpack_convert(oh.get(), f, symbol_set{}), std::invalid_argument,
388                     [](const std::invalid_argument &ia) {
389                         return boost::contains(
390                             ia.what(),
391                             "incompatible symbol set in monomial serialization: the reference "
392                             "symbol set has a size of 0, while the monomial being deserialized has a size of 2");
393                     });
394             }
395             // Random checks.
396             random_test<U>();
397         }
398         template <typename U, typename V = T, typename std::enable_if<std::is_same<V, integer>::value, int>::type = 0>
random_testmsgpack_tester::runner399         void random_test() const
400         {
401             using monomial_type = monomial<T, U>;
402             using size_type = typename monomial_type::size_type;
403             std::atomic<bool> flag(true);
404             auto checker = [&flag](unsigned n) {
405                 std::mt19937 eng(static_cast<std::mt19937::result_type>(n));
406                 std::uniform_int_distribution<size_type> sdist(0u, 10u);
407                 std::uniform_int_distribution<int> edist(-10, 10);
408                 const std::vector<std::string> vs = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
409                 for (auto f : {msgpack_format::portable, msgpack_format::binary}) {
410                     for (auto i = 0; i < ntrials; ++i) {
411                         const auto size = sdist(eng);
412                         std::vector<T> tmp;
413                         for (size_type j = 0; j < size; ++j) {
414                             tmp.emplace_back(edist(eng));
415                         }
416                         monomial_type m(tmp.begin(), tmp.end());
417                         symbol_set ss(vs.begin(), vs.begin() + size);
418                         if (m != msgpack_round_trip_monomial(m, ss, f)) {
419                             flag.store(false);
420                         }
421                         if (m != msgpack_round_trip_monomial_ss(m, ss, f)) {
422                             flag.store(false);
423                         }
424                     }
425                 }
426             };
427             std::thread t0(checker, 0);
428             std::thread t1(checker, 1);
429             std::thread t2(checker, 2);
430             std::thread t3(checker, 3);
431             t0.join();
432             t1.join();
433             t2.join();
434             t3.join();
435             BOOST_CHECK(flag.load());
436         }
437         template <typename U, typename V = T, typename std::enable_if<std::is_same<V, rational>::value, int>::type = 0>
random_testmsgpack_tester::runner438         void random_test() const
439         {
440             using monomial_type = monomial<T, U>;
441             using size_type = typename monomial_type::size_type;
442             std::atomic<bool> flag(true);
443             auto checker = [&flag](unsigned n) {
444                 std::mt19937 eng(static_cast<std::mt19937::result_type>(n));
445                 std::uniform_int_distribution<size_type> sdist(0u, 10u);
446                 std::uniform_int_distribution<int> edist(-10, 10);
447                 const std::vector<std::string> vs = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
448                 for (auto f : {msgpack_format::portable, msgpack_format::binary}) {
449                     for (auto i = 0; i < ntrials; ++i) {
450                         const auto size = sdist(eng);
451                         std::vector<T> tmp;
452                         for (size_type j = 0; j < size; ++j) {
453                             int num = edist(eng), den = edist(eng);
454                             if (!den) {
455                                 den = 1;
456                             }
457                             tmp.emplace_back(num, den);
458                         }
459                         monomial_type m(tmp.begin(), tmp.end());
460                         symbol_set ss(vs.begin(), vs.begin() + size);
461                         if (m != msgpack_round_trip_monomial(m, ss, f)) {
462                             flag.store(false);
463                         }
464                         if (m != msgpack_round_trip_monomial_ss(m, ss, f)) {
465                             flag.store(false);
466                         }
467                     }
468                 }
469             };
470             std::thread t0(checker, 0);
471             std::thread t1(checker, 1);
472             std::thread t2(checker, 2);
473             std::thread t3(checker, 3);
474             t0.join();
475             t1.join();
476             t2.join();
477             t3.join();
478             BOOST_CHECK(flag.load());
479         }
480         template <typename U, typename V = T, typename std::enable_if<std::is_integral<V>::value, int>::type = 0>
random_testmsgpack_tester::runner481         void random_test() const
482         {
483             using monomial_type = monomial<T, U>;
484             using size_type = typename monomial_type::size_type;
485             std::atomic<bool> flag(true);
486             auto checker = [&flag](unsigned n) {
487                 std::mt19937 eng(static_cast<std::mt19937::result_type>(n));
488                 std::uniform_int_distribution<size_type> sdist(0u, 10u);
489                 std::uniform_int_distribution<T> edist(-10, 10);
490                 const std::vector<std::string> vs = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"};
491                 for (auto f : {msgpack_format::portable, msgpack_format::binary}) {
492                     for (auto i = 0; i < ntrials; ++i) {
493                         const auto size = sdist(eng);
494                         std::vector<T> tmp;
495                         for (size_type j = 0; j < size; ++j) {
496                             tmp.push_back(edist(eng));
497                         }
498                         monomial_type m(tmp.begin(), tmp.end());
499                         symbol_set ss(vs.begin(), vs.begin() + size);
500                         if (m != msgpack_round_trip_monomial(m, ss, f)) {
501                             flag.store(false);
502                         }
503                         if (m != msgpack_round_trip_monomial_ss(m, ss, f)) {
504                             flag.store(false);
505                         }
506                     }
507                 }
508             };
509             std::thread t0(checker, 0);
510             std::thread t1(checker, 1);
511             std::thread t2(checker, 2);
512             std::thread t3(checker, 3);
513             t0.join();
514             t1.join();
515             t2.join();
516             t3.join();
517             BOOST_CHECK(flag.load());
518         }
519     };
520     template <typename T>
operator ()msgpack_tester521     void operator()(const T &) const
522     {
523         tuple_for_each(size_types{}, runner<T>());
524     }
525 };
526 
BOOST_AUTO_TEST_CASE(monomial_msgpack_test)527 BOOST_AUTO_TEST_CASE(monomial_msgpack_test)
528 {
529     tuple_for_each(expo_types{}, msgpack_tester());
530     BOOST_CHECK((!key_has_msgpack_pack<msgpack::sbuffer, monomial<fake_int_01>>::value));
531     BOOST_CHECK((!key_has_msgpack_pack<std::ostringstream, monomial<fake_int_01>>::value));
532     BOOST_CHECK((!key_has_msgpack_pack<sw<std::ostringstream>, monomial<fake_int_01>>::value));
533     BOOST_CHECK((!key_has_msgpack_convert<monomial<fake_int_01>>::value));
534 }
535 
536 #endif
537