22 #ifndef otbOGRFieldWrapper_hxx
23 #define otbOGRFieldWrapper_hxx
29 #include "otbConfigure.h"
32 #include <boost/mpl/map.hpp>
33 #include <boost/mpl/vector.hpp>
34 #include <boost/mpl/pair.hpp>
35 #include <boost/mpl/int.hpp>
36 #include <boost/mpl/at.hpp>
37 #include <boost/mpl/assert.hpp>
40 #include <boost/static_assert.hpp>
41 #if defined(__GNUC__) || defined(__clang__)
42 #pragma GCC diagnostic push
43 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
44 #include <boost/range/size.hpp>
45 #pragma GCC diagnostic pop
47 #include <boost/range/size.hpp>
50 #include <boost/type_traits/is_same.hpp>
52 #include "boost/type_traits/is_contiguous.h"
54 #if defined(__GNUC__) || defined(__clang__)
55 #pragma GCC diagnostic push
56 #pragma GCC diagnostic ignored "-Wshadow"
57 #include "ogr_feature.h"
58 #pragma GCC diagnostic pop
60 #include "ogr_feature.h"
62 #include "cpl_string.h"
85 namespace mpl = boost::mpl;
94 typedef mpl::map<mpl::pair<int, mpl::int_<OFTInteger>>, mpl::pair<std::vector<int>, mpl::int_<OFTIntegerList>>, mpl::pair<double, mpl::int_<OFTReal>>,
95 mpl::pair<std::vector<double>, mpl::int_<OFTRealList>>, mpl::pair<std::string, mpl::int_<OFTString>>, mpl::pair<char*, mpl::int_<OFTString>>,
96 mpl::pair<char const*, mpl::int_<OFTString>>, mpl::pair<std::vector<std::string>, mpl::int_<OFTStringList>>,
97 mpl::pair<GIntBig, mpl::int_<OFTInteger64>>, mpl::pair<std::vector<GIntBig>, mpl::int_<OFTInteger64List>>
120 #if GDAL_VERSION_NUM >= 2030000
122 T (OGRFeature::*ptr_to_function)(int)
const
125 T (OGRFeature::*ptr_to_function)(int)
128 typename FinalReturnType = T>
132 static FinalReturnType
call(OGRFeature& f,
int index)
134 return (f.*ptr_to_function)(index);
151 template <
typename FinalReturnType = std::vector<std::
string>>
155 static FinalReturnType
call(OGRFeature& f,
int index)
157 char** sl = f.GetFieldAsStringList(index);
158 FinalReturnType res(sl, sl + CSLCount(sl));
176 template <
typename T,
void (OGRFeature::*ptr_to_function)(
int, T value),
typename ActualParamType = T>
180 static void call(OGRFeature& f,
int index, T
const& value)
182 (f.*ptr_to_function)(index, value);
201 #if GDAL_VERSION_NUM >= 2030000
203 T
const* (OGRFeature::*ptr_to_function)(
int,
int*)
const
206 T
const* (OGRFeature::*ptr_to_function)(
int,
int*)
209 typename FinalReturnType = std::vector<T>>
213 static FinalReturnType
call(OGRFeature& f,
int index)
216 T
const* raw_container = (f.*ptr_to_function)(index, &nb);
217 const FinalReturnType res(raw_container + 0, raw_container + nb);
235 #if GDAL_VERSION_NUM >= 2030000
237 void (OGRFeature::*ptr_to_function)(int, int,
const T*)
240 void (OGRFeature::*ptr_to_function)(int, int, T*)
243 typename ActualParamType = std::vector<T>,
bool Is_contiguous = boost::is_contiguous<ActualParamType>::value>
249 #if GDAL_VERSION_NUM >= 2030000
251 void (OGRFeature::*ptr_to_function)(int, int,
const T*)
254 void (OGRFeature::*ptr_to_function)(int, int, T*)
257 typename ActualParamType>
261 static void call(OGRFeature& f,
int index, ActualParamType
const& container)
263 const int nb = boost::size(container);
264 (f.*ptr_to_function)(index, nb,
const_cast<T*
>(&container[0]));
272 #if GDAL_VERSION_NUM >= 2030000
274 void (OGRFeature::*ptr_to_function)(int, int,
const T*)
277 void (OGRFeature::*ptr_to_function)(int, int, T*)
280 typename ActualParamType>
284 static void call(OGRFeature& f,
int index, ActualParamType
const& container)
286 const int nb = boost::size(container);
287 std::vector<T> v(boost::begin(container), boost::end(container));
288 (f.*ptr_to_function)(index, nb, &v[0]);
304 template <
typename ActualParamType>
308 static void call(OGRFeature& f,
int index, ActualParamType
const& container)
329 #if GDAL_VERSION_NUM >= 2030000
331 void (OGRFeature::*ptr_to_function)(int, int,
const T*)
334 void (OGRFeature::*ptr_to_function)(int, int, T*)
337 typename ActualParamType = std::vector<T>>
341 static void call(OGRFeature& f,
int index, ActualParamType
const& container)
354 typedef mpl::map<mpl::pair<mpl::int_<OFTInteger>, MemberGetterPtr<int, &OGRFeature::GetFieldAsInteger>>,
355 mpl::pair<mpl::int_<OFTIntegerList>, MemberContainerGetterPtr<int, &OGRFeature::GetFieldAsIntegerList>>,
356 mpl::pair<mpl::int_<OFTReal>, MemberGetterPtr<double, &OGRFeature::GetFieldAsDouble>>,
357 mpl::pair<mpl::int_<OFTRealList>, MemberContainerGetterPtr<double, &OGRFeature::GetFieldAsDoubleList>>,
358 mpl::pair<mpl::int_<OFTString>, MemberGetterPtr<char const*, &OGRFeature::GetFieldAsString, std::string>>,
359 mpl::pair<mpl::int_<OFTStringList>, StringListMemberGetterPtr<std::vector<std::string>>>,
360 mpl::pair<mpl::int_<OFTInteger64>, MemberGetterPtr<GIntBig, &OGRFeature::GetFieldAsInteger64>>,
361 mpl::pair<mpl::int_<OFTInteger64List>, MemberContainerGetterPtr<GIntBig, &OGRFeature::GetFieldAsInteger64List>>>
374 mpl::pair<mpl::int_<OFTString>,
MemberSetterPtr<
char const*, &OGRFeature::SetField >>,
389 template <
typename T>
403 template <
typename T, std::
size_t N>
420 static char const*
convert(std::string
const& value)
422 return value.c_str();
437 assert(
m_Feature &&
"OGR Fields must be associated to a valid feature");
438 assert(m_index < m_Feature->GetFieldCount() &&
"Out-of-range index for a OGR field");
439 assert(
m_Feature->GetFieldDefnRef(
m_index) &&
"No definition available for the OGR field");
442 template <
typename T>
447 typedef typename Converter::type InterfaceType;
450 BOOST_MPL_ASSERT_MSG(!boost::is_array<InterfaceType>::value, InterFaceType_Cant_Be_An_array, (T, InterfaceType));
451 typedef typename boost::mpl::at<internal::FieldType_Map, InterfaceType>::type Kind;
452 BOOST_MPL_ASSERT_MSG(!(boost::is_same<Kind, boost::mpl::void_>::value), UNEXPECTED_KIND_TYPE, (T, InterfaceType, Kind));
454 assert(m_Definition.GetType() == Kind::value &&
"OGR field type mismatches the type of new field value");
455 typedef typename boost::mpl::at<internal::FieldSetters_Map, Kind>::type SetterType;
458 BOOST_MPL_ASSERT_NOT((boost::is_same<SetterType, boost::mpl::void_>));
459 SetterType::call(*m_Feature, m_index, Converter::convert(value));
462 template <
typename T>
466 assert(HasBeenSet() &&
"Cannot access the value of a field that hasn't been set");
467 typedef typename boost::mpl::at<internal::FieldType_Map, T>::type Kind;
469 BOOST_STATIC_ASSERT(!(boost::is_same<Kind, boost::mpl::void_>::value));
470 typedef typename boost::mpl::at<internal::FieldGetters_Map, Kind>::type GetterType;
473 BOOST_STATIC_ASSERT(!(boost::is_same<GetterType, boost::mpl::void_>::value));
474 return GetterType::call(*m_Feature, m_index);
480 return UncheckedPrintSelf(os, indent);
486 return UncheckedHasBeenSet();
499 assert(f.
GetType() == this->GetType() &&
"Cannot assign from a field that doesn't have the same definition");
511 OGRField* f = m_Feature->GetRawFieldRef(m_index);
512 assert(f &&
"The field obtained shall not be null");
518 return const_cast<Field*
>(
this)->ogr();
521 #endif // otbOGRFieldWrapper_hxx