File Coverage

t/cookbook/recipe12.xsi
Criterion Covered Total %
statement 1 25 4.0
branch 0 56 0.0
condition n/a
subroutine n/a
pod n/a
total 1 81 1.2


line stmt bran cond sub pod time code
1             MODE: INLINE
2              
3             #include
4             #include
5              
6             struct PointRecipe12 {
7             double x;
8             double y;
9             };
10              
11             double distance(const PointRecipe12& pt_a, const PointRecipe12& pt_b) {
12             auto dx = pt_a.x - pt_a.x;
13             auto dy = pt_a.y - pt_b.y;
14             return std::sqrt(dx * dx + dy * dy);
15             }
16              
17             struct StatisticsRecipe12 {
18             StatisticsRecipe12(const PointRecipe12& interest_, const std::vector& points_): interest{interest_}, points{points_} {
19             if(points.empty()) throw std::runtime_error("points cannot be empty");
20             }
21              
22             const PointRecipe12& nearest() const {
23             return select([](const double& prev_dist, const double& new_dist) { return new_dist < prev_dist; } );
24             }
25              
26             const PointRecipe12& farest() const {
27             return select([](const double& prev_dist, const double& new_dist) { return new_dist > prev_dist; } );
28             }
29              
30             private:
31             template
32             const PointRecipe12& select(F&& fn) const {
33             const PointRecipe12* pt = &points.front();
34             auto best_distance = distance(interest, *pt);
35             for(auto it = points.cbegin() + 1; it != points.cend(); ++it) {
36             auto new_distance = distance(interest, *it);
37             if(fn(best_distance, new_distance)) {
38             pt = &*it;
39             best_distance = new_distance;
40             }
41             }
42             return *pt;
43             }
44              
45             const PointRecipe12& interest;
46             const std::vector& points;
47             };
48              
49              
50             namespace xs {
51             template <>
52             struct Typemap : TypemapObject {
53             static std::string package () { return "MyTest::Cookbook::PointRecipe12"; }
54             };
55              
56              
57             template <>
58             struct Typemap : TypemapObject {
59             static std::string package () { return "MyTest::Cookbook::StatisticsRecipe12"; }
60             };
61             }
62              
63             static xs::Sv::payload_marker_t payload_marker_12;
64              
65             struct StatisticsRecipe12_payload {
66             PointRecipe12 interest;
67             std::vector points;
68             ~StatisticsRecipe12_payload() { std::cout << "~StatisticsRecipe12_payload\n"; }
69             };
70              
71             static int payload_marker_IntersectionFinderAdder_free(pTHX_ SV*, MAGIC* mg) {
72             if (mg->mg_virtual == &payload_marker_12) {
73             auto* payload = static_cast((void*)mg->mg_ptr);
74             delete payload;
75             }
76             return 0;
77             }
78              
79             MODULE = MyTest::Cookbook PACKAGE = MyTest::Cookbook::PointRecipe12
80             PROTOTYPES: DISABLE
81              
82             double PointRecipe12::x(SV* new_val = nullptr) : ALIAS(y = 1) {
83 0           double* val = nullptr;
84 0 0         switch(ix) {
85 0           case 1: val = &THIS->y; break;
86 0           default: val = &THIS->x; break;
87             }
88 0 0         if (new_val) {
89 0 0         *val = SvNV(new_val);
    0          
90             }
91 0           RETVAL = *val;
92             }
93              
94             PointRecipe12* PointRecipe12::new(double x = 0, double y = 0) {
95 0           RETVAL = new PointRecipe12{x, y};
96 0 0         }
97 0 0          
98              
99             MODULE = MyTest::Cookbook PACKAGE = MyTest::Cookbook::StatisticsRecipe12
100             PROTOTYPES: DISABLE
101              
102             PointRecipe12* StatisticsRecipe12::nearest() {
103 0           RETVAL = new PointRecipe12(THIS->nearest());
104 0 0         }
    0          
105              
106             PointRecipe12* StatisticsRecipe12::farest() {
107 0           RETVAL = new PointRecipe12(THIS->farest());
108 0 0         }
    0          
109              
110             Sv StatisticsRecipe12::new(PointRecipe12* interest, Array pts) {
111             using payload_ptr_t = std::unique_ptr;
112             using stats_ptr_t = std::unique_ptr;
113              
114 0 0         std::vector points;
115 0 0         for(auto it: pts) {
    0          
    0          
    0          
116 0 0         points.push_back(*(xs::in(it)));
    0          
117             }
118              
119             // better to use std::make_unique from C++ 14, if available.
120 0 0         auto payload_holder = payload_ptr_t{new StatisticsRecipe12_payload{ *interest, std::move(points) }};
    0          
121 0 0         auto self_holder = stats_ptr_t{new StatisticsRecipe12{ payload_holder->interest, payload_holder->points }};
    0          
    0          
122              
123 0 0         Object self = xs::out(self_holder.get(), CLASS);
    0          
    0          
124 0 0         self.payload_attach((void*)payload_holder.get(), &payload_marker_12);
125              
126 0           payload_holder.release();
127 0           self_holder.release();
128              
129 0 0         RETVAL = self.ref();
    0          
130             }
131              
132             BOOT {
133 34           payload_marker_12.svt_free = payload_marker_IntersectionFinderAdder_free;
134             }