]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/util/select_most_precise.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / util / select_most_precise.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6
7// This file was modified by Oracle on 2014.
8// Modifications copyright (c) 2014 Oracle and/or its affiliates.
9
10// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11
12// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
14
15// Use, modification and distribution is subject to the Boost Software License,
16// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17// http://www.boost.org/LICENSE_1_0.txt)
18
19#ifndef BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
20#define BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
21
22#include <boost/mpl/if.hpp>
23#include <boost/type_traits/is_floating_point.hpp>
24#include <boost/type_traits/is_fundamental.hpp>
25
26
27namespace boost { namespace geometry
28{
29
30#ifndef DOXYGEN_NO_DETAIL
31
32namespace detail { namespace select_most_precise
33{
34
35
36// At least one of the types is non-fundamental. Take that one.
37// if both are non-fundamental, the type-to-be-selected
38// is unknown, it should be defined by explicit specialization.
39template <bool Fundamental1, bool Fundamental2, typename T1, typename T2>
40struct select_non_fundamental
41{
42 typedef T1 type;
43};
44
45template <typename T1, typename T2>
46struct select_non_fundamental<true, false, T1, T2>
47{
48 typedef T2 type;
49};
50
51template <typename T1, typename T2>
52struct select_non_fundamental<false, true, T1, T2>
53{
54 typedef T1 type;
55};
56
57
58// Selection of largest type (e.g. int of <short int,int>
59// It defaults takes the first one, if second is larger, take the second one
60template <bool SecondLarger, typename T1, typename T2>
61struct select_largest
62{
63 typedef T1 type;
64};
65
66template <typename T1, typename T2>
67struct select_largest<true, T1, T2>
68{
69 typedef T2 type;
70};
71
72
73
74// Selection of floating point and specializations:
75// both FP or both !FP does never occur...
76template <bool FP1, bool FP2, typename T1, typename T2>
77struct select_floating_point
78{
79 typedef char type;
80};
81
82
83// ... so if ONE but not both of these types is floating point, take that one
84template <typename T1, typename T2>
85struct select_floating_point<true, false, T1, T2>
86{
87 typedef T1 type;
88};
89
90
91template <typename T1, typename T2>
92struct select_floating_point<false, true, T1, T2>
93{
94 typedef T2 type;
95};
96
97
98}} // namespace detail::select_most_precise
99#endif // DOXYGEN_NO_DETAIL
100
101
102/*!
103 \brief Meta-function to select, of two types, the most accurate type for
104 calculations
105 \ingroup utility
106 \details select_most_precise classes, compares two types on compile time.
107 For example, if an addition must be done with a double and an integer, the
108 result must be a double.
109 If both types are integer, the result can be an integer.
110 \note It is different from the "promote" class, already in boost. That
111 class promotes e.g. a (one) float to a double. This class selects a
112 type from two types. It takes the most accurate, but does not promote
113 afterwards.
114 \note This traits class is completely independant from GGL and might be a
115 separate addition to Boost
116 \note If the input is a non-fundamental type, it might be a calculation
117 type such as a GMP-value or another high precision value. Therefore,
118 if one is non-fundamental, that one is chosen.
119 \note If both types are non-fundamental, the result is indeterminate and
120 currently the first one is chosen.
121*/
122template <typename T1, typename T2 = void, typename T3 = void>
123struct select_most_precise
124{
125 typedef typename select_most_precise
126 <
127 typename select_most_precise<T1, T2>::type,
128 T3
129 >::type type;
130};
131
132template <typename T1, typename T2>
133struct select_most_precise<T1, T2, void>
134{
135 static const bool second_larger = sizeof(T2) > sizeof(T1);
136 static const bool one_not_fundamental = !
137 (boost::is_fundamental<T1>::type::value
138 && boost::is_fundamental<T2>::type::value);
139
140 static const bool both_same =
141 boost::is_floating_point<T1>::type::value
142 == boost::is_floating_point<T2>::type::value;
143
144 typedef typename boost::mpl::if_c
145 <
146 one_not_fundamental,
147 typename detail::select_most_precise::select_non_fundamental
148 <
149 boost::is_fundamental<T1>::type::value,
150 boost::is_fundamental<T2>::type::value,
151 T1,
152 T2
153 >::type,
154 typename boost::mpl::if_c
155 <
156 both_same,
157 typename detail::select_most_precise::select_largest
158 <
159 second_larger,
160 T1,
161 T2
162 >::type,
163 typename detail::select_most_precise::select_floating_point
164 <
165 boost::is_floating_point<T1>::type::value,
166 boost::is_floating_point<T2>::type::value,
167 T1,
168 T2
169 >::type
170 >::type
171 >::type type;
172};
173
174template <typename T1>
175struct select_most_precise<T1, void, void>
176{
177 typedef T1 type;
178};
179
180}} // namespace boost::geometry
181
182#endif // BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP