]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/yap/test/lazy_vector_alloc_test.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / yap / test / lazy_vector_alloc_test.cpp
1 // Copyright (C) 2016-2018 T. Zachary Laine
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 #include <boost/yap/expression.hpp>
7
8 #include <algorithm>
9 #include <cassert>
10 #include <iostream>
11 #include <vector>
12
13 #include <boost/test/minimal.hpp>
14
15
16 int allocations = 0;
17
18 void * operator new(std::size_t size)
19 {
20 ++allocations;
21 void * retval = malloc(size);
22 if (!retval)
23 throw std::bad_alloc();
24 return retval;
25 }
26
27 void operator delete(void * ptr) noexcept { free(ptr); }
28
29
30 template<boost::yap::expr_kind Kind, typename Tuple>
31 struct lazy_vector_expr;
32
33
34 struct take_nth
35 {
36 boost::yap::terminal<lazy_vector_expr, double> operator()(
37 boost::yap::terminal<lazy_vector_expr, std::vector<double>> const &
38 expr);
39
40 std::size_t n;
41 };
42
43 template<boost::yap::expr_kind Kind, typename Tuple>
44 struct lazy_vector_expr
45 {
46 static const boost::yap::expr_kind kind = Kind;
47
48 Tuple elements;
49
50 auto operator[](std::size_t n) const
51 {
52 return boost::yap::evaluate(boost::yap::transform(*this, take_nth{n}));
53 }
54 };
55
56 BOOST_YAP_USER_BINARY_OPERATOR(plus, lazy_vector_expr, lazy_vector_expr)
57 BOOST_YAP_USER_BINARY_OPERATOR(minus, lazy_vector_expr, lazy_vector_expr)
58
59 boost::yap::terminal<lazy_vector_expr, double> take_nth::operator()(
60 boost::yap::terminal<lazy_vector_expr, std::vector<double>> const & expr)
61 {
62 double x = boost::yap::value(expr)[n];
63 return boost::yap::make_terminal<lazy_vector_expr, double>(std::move(x));
64 }
65
66 struct lazy_vector : lazy_vector_expr<
67 boost::yap::expr_kind::terminal,
68 boost::hana::tuple<std::vector<double>>>
69 {
70 lazy_vector() {}
71
72 explicit lazy_vector(std::vector<double> && vec)
73 {
74 elements = boost::hana::tuple<std::vector<double>>(std::move(vec));
75 }
76
77 template<boost::yap::expr_kind Kind, typename Tuple>
78 lazy_vector & operator+=(lazy_vector_expr<Kind, Tuple> const & rhs)
79 {
80 std::vector<double> & this_vec = boost::yap::value(*this);
81 for (int i = 0, size = (int)this_vec.size(); i < size; ++i) {
82 this_vec[i] += rhs[i];
83 }
84 return *this;
85 }
86 };
87
88
89 int test_main(int, char * [])
90 {
91 lazy_vector v1{std::vector<double>(4, 1.0)};
92 lazy_vector v2{std::vector<double>(4, 2.0)};
93 lazy_vector v3{std::vector<double>(4, 3.0)};
94
95 // Reset allocation count. There should be none from this point on.
96 allocations = 0;
97
98 double d1 = (v2 + v3)[2];
99 std::cout << d1 << "\n";
100
101 v1 += v2 - v3;
102 std::cout << '{' << v1[0] << ',' << v1[1] << ',' << v1[2] << ',' << v1[3]
103 << '}' << "\n";
104
105 BOOST_CHECK(allocations == 0);
106
107 return 0;
108 }