1 /* Inline functions implementing distances.
2    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3    Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #ifndef PPL_distances_inlines_hh
25 #define PPL_distances_inlines_hh 1
26 
27 #include "Result_defs.hh"
28 
29 namespace Parma_Polyhedra_Library {
30 
31 // A struct to work around the lack of partial specialization
32 // of function templates in C++.
33 template <typename To, typename From>
34 struct maybe_assign_struct {
35   static inline Result
functionParma_Polyhedra_Library::maybe_assign_struct36   function(const To*& top, To& tmp, const From& from, Rounding_Dir dir) {
37     // When `To' and `From' are different types, we make the conversion
38     // and use `tmp'.
39     top = &tmp;
40     return assign_r(tmp, from, dir);
41   }
42 };
43 
44 template <typename Type>
45 struct maybe_assign_struct<Type, Type> {
46   static inline Result
functionParma_Polyhedra_Library::maybe_assign_struct47   function(const Type*& top, Type&, const Type& from, Rounding_Dir) {
48     // When the types are the same, conversion is unnecessary.
49     top = &from;
50     return V_EQ;
51   }
52 };
53 
54 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
55 /*! \brief
56   Assigns to \p top a pointer to a location that holds the
57   conversion, according to \p dir, of \p from to type \p To.  When
58   necessary, and only when necessary, the variable \p tmp is used to
59   hold the result of conversion.
60 */
61 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
62 template <typename To, typename From>
63 inline Result
maybe_assign(const To * & top,To & tmp,const From & from,Rounding_Dir dir)64 maybe_assign(const To*& top, To& tmp, const From& from, Rounding_Dir dir) {
65   return maybe_assign_struct<To, From>::function(top, tmp, from, dir);
66 }
67 
68 template <typename Temp>
69 inline void
combine(Temp & running,const Temp & current,Rounding_Dir dir)70 Rectilinear_Distance_Specialization<Temp>::combine(Temp& running,
71                                                    const Temp& current,
72                                                    Rounding_Dir dir) {
73   add_assign_r(running, running, current, dir);
74 }
75 
76 template <typename Temp>
77 inline void
finalize(Temp &,Rounding_Dir)78 Rectilinear_Distance_Specialization<Temp>::finalize(Temp&, Rounding_Dir) {
79 }
80 
81 template <typename Temp>
82 inline void
combine(Temp & running,Temp & current,Rounding_Dir dir)83 Euclidean_Distance_Specialization<Temp>::combine(Temp& running,
84                                                  Temp& current,
85                                                  Rounding_Dir dir) {
86   mul_assign_r(current, current, current, dir);
87   add_assign_r(running, running, current, dir);
88 }
89 
90 template <typename Temp>
91 inline void
finalize(Temp & running,Rounding_Dir dir)92 Euclidean_Distance_Specialization<Temp>::finalize(Temp& running,
93                                                   Rounding_Dir dir) {
94   sqrt_assign_r(running, running, dir);
95 }
96 
97 template <typename Temp>
98 inline void
combine(Temp & running,const Temp & current,Rounding_Dir)99 L_Infinity_Distance_Specialization<Temp>::combine(Temp& running,
100                                                   const Temp& current,
101                                                   Rounding_Dir) {
102   if (current > running) {
103     running = current;
104   }
105 }
106 
107 template <typename Temp>
108 inline void
finalize(Temp &,Rounding_Dir)109 L_Infinity_Distance_Specialization<Temp>::finalize(Temp&, Rounding_Dir) {
110 }
111 
112 } // namespace Parma_Polyhedra_Library
113 
114 #endif // !defined(PPL_distances_inlines_hh)
115