Skip to content

Commit 76cdbe6

Browse files
committed
Replace code_elements in epsg with statically sized type for faster compile times and replace binary search with perfect hashing.
1 parent 3f5c044 commit 76cdbe6

File tree

5 files changed

+7500
-7233
lines changed

5 files changed

+7500
-7233
lines changed

include/boost/geometry/srs/projections/code.hpp

+127-15
Original file line numberDiff line numberDiff line change
@@ -10,42 +10,154 @@
1010
#ifndef BOOST_GEOMETRY_PROJECTIONS_CODE_HPP
1111
#define BOOST_GEOMETRY_PROJECTIONS_CODE_HPP
1212

13-
14-
#include <algorithm>
13+
#include <cstdint>
1514

1615
#include <boost/geometry/srs/projections/dpar.hpp>
1716

18-
1917
namespace boost { namespace geometry { namespace projections
2018
{
2119

22-
2320
#ifndef DOXYGEN_NO_DETAIL
2421
namespace detail
2522
{
2623

24+
template <std::size_t MaxParams, bool HasTowgs84 = true>
2725
struct code_element
2826
{
27+
union parameter_variant
28+
{
29+
bool b;
30+
int i;
31+
double v;
32+
//spheroid
33+
//nadgrids,
34+
//towgs84
35+
};
36+
2937
int code;
30-
srs::dpar::parameters<> parameters;
38+
std::int8_t parameter_count;
39+
std::int8_t towgs84_size {0};
40+
// Not bundling the following together into a struct to avoid 8-byte-alignment.
41+
std::int8_t parameter_variant_tags[MaxParams];
42+
std::int16_t parameter_ids[MaxParams];
43+
parameter_variant parameters[MaxParams];
44+
double towgs84_data[7];
3145
};
3246

33-
struct code_element_less
47+
template <std::size_t MaxParams>
48+
struct code_element<MaxParams, false>
3449
{
35-
inline bool operator()(code_element const& l, code_element const& r) const
50+
union parameter_variant
3651
{
37-
return l.code < r.code;
52+
bool b;
53+
int i;
54+
double v;
55+
};
56+
57+
int code;
58+
std::int8_t parameter_count;
59+
std::int8_t parameter_variant_tags[MaxParams];
60+
std::int16_t parameter_ids[MaxParams];
61+
parameter_variant parameters[MaxParams];
62+
};
63+
64+
template <bool HasTowgs84 = true>
65+
struct code_element_to_towgs84
66+
{
67+
template <std::size_t MaxParams>
68+
static void apply(code_element<MaxParams, true> const& e,
69+
srs::dpar::parameters<double>& out)
70+
{
71+
using p = srs::dpar::parameter<double>;
72+
out(p(srs::dpar::name_towgs84::towgs84,
73+
srs::detail::towgs84<double>(e.towgs84_data, e.towgs84_data + e.towgs84_size)));
3874
}
3975
};
4076

41-
template<typename RandIt>
42-
inline RandIt binary_find_code_element(RandIt first, RandIt last, int code)
77+
template <>
78+
struct code_element_to_towgs84<false>
79+
{
80+
template <std::size_t MaxParams>
81+
static void apply(code_element<MaxParams, false> const&, srs::dpar::parameters<double>&) {}
82+
};
83+
84+
85+
template <std::size_t MaxParams, bool HasTowgs84>
86+
inline srs::dpar::parameters<>
87+
code_element_to_dpar_parameters(code_element<MaxParams, HasTowgs84> const& e)
4388
{
44-
code_element_less comp;
45-
code_element value;
46-
value.code = code;
47-
first = std::lower_bound(first, last, value, comp);
48-
return first != last && !comp(value, *first) ? first : last;
89+
using namespace srs::dpar;
90+
using p = srs::dpar::parameter<double>;
91+
srs::dpar::parameters<> out;
92+
out.reserve(e.parameter_count);
93+
for (int i = 0; i < e.parameter_count; ++i)
94+
{
95+
auto const& id = e.parameter_ids[i];
96+
auto const& pv = e.parameters[i];
97+
auto const& tag = e.parameter_variant_tags[i];
98+
if (id == -1)
99+
{
100+
out(p());
101+
}
102+
else if (id < static_cast<int>(name_r::alpha)) // f
103+
{
104+
out(p(static_cast<name_f>(id), pv.v));
105+
}
106+
else if (id < static_cast<int>(name_i::aperture)) // r
107+
{
108+
out(p(static_cast<name_r>(id), pv.v));
109+
}
110+
else if (id < static_cast<int>(name_be::czech)) // i
111+
{
112+
out(p(static_cast<name_i>(id), pv.i));
113+
}
114+
else if (id < static_cast<int>(name_datum::datum)) // be
115+
{
116+
out(p(static_cast<name_be>(id), pv.b));
117+
}
118+
else if (id == static_cast<int>(name_datum::datum)) //datum
119+
{
120+
out(p(name_datum::datum, static_cast<value_datum>(pv.i)));
121+
}
122+
else if ( id == static_cast<int>(name_ellps::ellps)) //ellps
123+
{
124+
out(p(name_ellps::ellps, static_cast<value_ellps>(pv.i)));
125+
}
126+
// no occurence of ellps with spheroid in arr
127+
// no occurence of mode in arr
128+
// no occurence of nadgrids in arr
129+
// no occurence of orient in arr
130+
else if (id == static_cast<name_pm>(name_pm::pm)) //pm
131+
{
132+
if (tag == 1)
133+
{
134+
out(p(name_pm::pm, static_cast<value_pm>(pv.i)));
135+
}
136+
else //if tag == 2
137+
{
138+
out(p(name_pm::pm, pv.v));
139+
}
140+
}
141+
else if (id < static_cast<int>(name_sweep::sweep)) // proj
142+
{
143+
out(p(static_cast<name_proj>(id), static_cast<value_proj>(pv.i)));
144+
}
145+
else if (id == static_cast<int>(name_sweep::sweep)) // sweep
146+
{
147+
out(p(name_sweep::sweep, static_cast<value_sweep>(pv.i)));
148+
}
149+
else if (id == static_cast<int>(name_towgs84::towgs84)) //towgs84
150+
{
151+
code_element_to_towgs84<HasTowgs84>::apply(e, out);
152+
}
153+
// no occurence of axis in arr
154+
else if (id == static_cast<int>(name_units::units)) //units
155+
{
156+
out(p(name_units::units, static_cast<value_units>(pv.i)));
157+
}
158+
// no occurence of vunits in arr
159+
}
160+
return out;
49161
}
50162

51163
}

include/boost/geometry/srs/projections/dpar.hpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,11 @@ struct parameter
722722
{
723723
return m_value.which() == srs::detail::find_type_index<variant_type, V>::value;
724724
}
725-
725+
#if defined(BOOST_GEOMETRY_ENABLE_SRS_PARAMETER_DEBUGGING)
726+
public:
727+
#else
726728
private:
729+
#endif
727730
int m_id;
728731
variant_type m_value;
729732
};
@@ -801,8 +804,9 @@ class parameters
801804
const_iterator begin() const { return m_params.begin(); }
802805
const_iterator end() const { return m_params.end(); }
803806
const_reference operator[](size_type i) const { return m_params[i]; }
804-
size_type size() { return m_params.size(); }
805-
bool empty() { return m_params.empty(); }
807+
size_type size() const { return m_params.size(); }
808+
bool empty() const { return m_params.empty(); }
809+
void reserve(std::size_t s) { m_params.reserve(s); }
806810

807811
private:
808812
container_type m_params;

0 commit comments

Comments
 (0)