diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx index b82f5a93dd1b43e38a67553d74813cbfd854d40e..e71aa18427169fb9889c8208ba9f7ca1e9ad12a1 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.cxx @@ -19,7 +19,9 @@ #include "otbOGRDataSourceWrapper.h" // standard includes #include <cassert> +#include <numeric> #include <boost/bind.hpp> +#include <boost/foreach.hpp> // ITK includes #include "itkMacro.h" // itkExceptionMacro #include "itkMetaDataObject.h" @@ -125,15 +127,11 @@ otb::ogr::DataSource::New(OGRDataSource * source) otb::ogr::DataSource::const_iterator otb::ogr::DataSource::cbegin() const { return const_iterator(*this, 0); - // assert(!"not-ready"); - // return const_iterator(); } otb::ogr::DataSource::const_iterator otb::ogr::DataSource::cend() const { return const_iterator(*this, GetLayersCount()); - // assert(!"not-ready"); - // return const_iterator(); } otb::ogr::DataSource::iterator otb::ogr::DataSource::begin() @@ -282,7 +280,7 @@ namespace { // Anonymous namespace { AccuLayersSizes(bool doForceComputation) : m_doForceComputation(doForceComputation) { } - int operator()(otb::ogr::Layer const& layer, int accumulated) const + int operator()(int accumulated, otb::ogr::Layer const& layer) const { const int loc_size = layer.GetFeatureCount(m_doForceComputation); return loc_size < 0 ? loc_size : loc_size+accumulated; @@ -294,7 +292,7 @@ namespace { // Anonymous namespace int otb::ogr::DataSource::Size(bool doForceComputation) const { - return AccumulateOnLayers(AccuLayersSizes(doForceComputation), 0); + return std::accumulate(begin(),end(), 0, AccuLayersSizes(doForceComputation)); } /*===========================================================================*/ @@ -306,7 +304,10 @@ void otb::ogr::DataSource::PrintSelf( std::ostream& os, itk::Indent indent) const { assert(m_DataSource && "Datasource not initialized"); - ForEachLayer(boost::bind(&Layer::PrintSelf, _1, boost::ref(os), indent.GetNextIndent())); + BOOST_FOREACH(Layer const l, *this) + { + l.PrintSelf(os, indent); + } } /*virtual*/ void otb::ogr::DataSource::Graft(const itk::DataObject * data) diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h index 8a22c7ec86c28f24cbfd179bd1fc306fc7982100..ebe867f9ce0e0914036b1a036ba960b4806a80ce 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.h @@ -248,9 +248,10 @@ public: * \see http://www.boost.org/doc/libs/1_49_0/libs/iterator/doc/iterator_facade.html#tutorial-example */ template <class Value> class layer_iter - : public boost::iterator_facade<layer_iter<Value>, Value, boost::random_access_traversal_tag> + : public boost::iterator_facade<layer_iter<Value>, Value, boost::random_access_traversal_tag, Value> { struct enabler {}; + /** Const-synchronized type of the \c DataSource container. * \internal * The definition of a new series of functions \c boost::copy_const, @@ -264,42 +265,25 @@ public: * So here is the hard-coded result of what \c boost::copy_const would have * given in order to avoid any licensing issue. */ - typedef typename boost::mpl::if_ - <boost::is_const<Value> - , otb::ogr::DataSource const - , otb::ogr::DataSource - >::type container_type; + typedef typename boost::mpl::if_ <boost::is_const<Value> , otb::ogr::DataSource const , otb::ogr::DataSource >::type + container_type; public: - layer_iter(container_type & datasource, size_t index) - : m_DataSource(&datasource), m_index(index) {} - layer_iter() - : m_DataSource(0), m_index(0) {} + layer_iter(container_type & datasource, size_t index); + layer_iter(); ; + template <class OtherValue> layer_iter( layer_iter<OtherValue> const& other, typename boost::enable_if<boost::is_convertible<OtherValue*,Value*> , enabler >::type = enabler() - ) - : m_DataSource(other.m_DataSource), m_index(other.m_index) - {} + ); private: friend class boost::iterator_core_access; template <class> friend class layer_iter; - template <class OtherValue> bool equal(layer_iter<OtherValue> const& other) const - { - return m_DataSource == other.m_DataSource && other.m_index == m_index; - } - void increment() - { - assert(m_DataSource && m_index < m_DataSource->GetLayersCount() && "cannot increment past end()"); - ++m_index; - } - Value dereference() const - { - assert(m_DataSource && m_index < m_DataSource->GetLayersCount() && "cannot dereference past end()"); - return m_DataSource->GetLayerUnchecked(m_index); - } + template <class OtherValue> bool equal(layer_iter<OtherValue> const& other) const; + void increment(); + Value dereference() const; container_type * m_DataSource; size_t m_index; @@ -317,29 +301,6 @@ public: iterator end (); //@} - /** - * Applies a functor on all layers. - * \param[in] f functor (copied) to execute on each layer. - * - * \throw itk::ExceptionObject in case one layer can't be accessed. - * \throw * whatever the functor \c may throw. - * \note the functor is expected to receive an \c ogr::Layer by reference. - * \sa std::for_each - */ - template <class Functor> void ForEachLayer(Functor f) const; - - /** - * Accumulates the result of a functor on all layers. - * \param[in] f functor (copied) to execute on each layer. - * - * \return the result accumulated (with +) - * \throw itk::ExceptionObject in case one layer can't be accessed. - * \throw * whatever the functor \c may throw. - * \note the functor is expected to receive an \c ogr::Layer by reference. - * \sa std::accumulate - */ - template <class Functor, typename V> V AccumulateOnLayers(Functor f, V v0) const; - /** Returns the number of elements in the Data Source. * \param[in] doForceComputation indicates whether the size shall be * computed on each layer even so it's expensive to do so. @@ -538,8 +499,7 @@ public: * boolean expression to be used in \c if tests. * \see <em>Imperfect C++</em>, Matthew Wilson, Addisson-Welsey, par 24.6 */ - operator int boolean ::* () const - { + operator int boolean ::* () const { return m_DataSource ? &boolean::i : 0; } @@ -587,6 +547,7 @@ protected: * \post the \c OGRDataSource owned is released (if not null). */ virtual ~DataSource(); + /** Prints self into stream. */ virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; @@ -602,6 +563,9 @@ private: * OGRDataSource::GetLayer(). */ OGRLayer* GetLayerUnchecked(size_t i); + /** @copydoc OGRLayer* otb::ogr::DataSource::GetLayerUnchecked(size_t i) + */ + OGRLayer* GetLayerUnchecked(size_t i) const; DataSource(const Self&); //purposely not implemented DataSource& operator =(const Self&); //purposely not implemented diff --git a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx index 3a456ee029c0ff1e1ae60dcfb8f111b066232f51..6281ada5e5e163168240d30df56246a7d5e1cfee 100644 --- a/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx +++ b/Code/UtilitiesAdapters/OGRAdapters/otbOGRDataSourceWrapper.txx @@ -32,11 +32,18 @@ #include "ogrsf_frmts.h" // OGRDataSource & OGRLayer /*===========================================================================*/ -/*==============================[ other stuff ]==============================*/ +/*=========================[ otb::ogr::DataSource ]==========================*/ /*===========================================================================*/ +// These function definitions are inline so assert() will be expanded according +// to the compilation mode of the client code. + +inline +OGRDataSource & otb::ogr::DataSource::ogr() +{ + assert(m_DataSource && "OGRDataSource not initialized"); + return *m_DataSource; +} -// This implementation is inline so assert() will be expanded according to the -// compilation mode of the client code. inline otb::ogr::Layer otb::ogr::DataSource::GetLayer(size_t i) { @@ -65,47 +72,59 @@ otb::ogr::Layer const otb::ogr::DataSource::GetLayerChecked(size_t i) const return const_cast <DataSource*>(this)->GetLayerChecked(i); } -template <class Functor, typename V> inline -V otb::ogr::DataSource::AccumulateOnLayers(Functor f, V v0) const +OGRLayer* otb::ogr::DataSource::GetLayerUnchecked(size_t i) const { - assert(m_DataSource && "OGRDataSource not initialized"); - const int nbLayers = this->GetLayersCount(); - for (int i=0; i!=nbLayers; ++i) - { - const Layer l = GetLayer(i); - if (!l) - { - itkExceptionMacro(<< "Failed to fetch "<< i <<"th layer from OGRDataSource"); - } - v0 = f(l, v0); - } - return v0; + return const_cast <DataSource*>(this)->GetLayerUnchecked(i); } -template <class Functor> -inline -void otb::ogr::DataSource::ForEachLayer(Functor f) const +/*===========================================================================*/ +/*====================[ otb::ogr::DataSource/iterators ]=====================*/ +/*===========================================================================*/ +template <class Value> +otb::ogr::DataSource::layer_iter<Value>::layer_iter(container_type & datasource, size_t index) +: m_DataSource(&datasource), m_index(index) +{} + +template <class Value> +otb::ogr::DataSource::layer_iter<Value>::layer_iter() +: m_DataSource(0), m_index(0) +{} + +template <class Value> +template <class OtherValue> otb::ogr::DataSource::layer_iter<Value>::layer_iter( + otb::ogr::DataSource::layer_iter<OtherValue> const& other, + typename boost::enable_if<boost::is_convertible<OtherValue*,Value*> + , enabler + >::type +) +: m_DataSource(other.m_DataSource), m_index(other.m_index) +{} + +template <class Value> +template <class OtherValue> +bool otb::ogr::DataSource::layer_iter<Value>::equal(layer_iter<OtherValue> const& other) const { - assert(m_DataSource && "OGRDataSource not initialized"); - const int nbLayers = this->GetLayersCount(); - for (int i=0; i!=nbLayers; ++i) - { - Layer l = GetLayer(i); - if (!l) - { - itkExceptionMacro(<< "Failed to fetch "<< i <<"th layer from OGRDataSource"); - } - f(l); - } + return m_DataSource == other.m_DataSource && other.m_index == m_index; } -#endif // __otbOGRDataSourceWrapper_txx +template <class Value> +void otb::ogr::DataSource::layer_iter<Value>::increment() +{ + assert(m_DataSource + && m_index < m_DataSource->GetLayersCount() + && "cannot increment past end()"); + ++m_index; +} -inline -OGRDataSource & otb::ogr::DataSource::ogr() +template <class Value> +Value otb::ogr::DataSource::layer_iter<Value>::dereference() const { - assert(m_DataSource && "OGRDataSource not initialized"); - return *m_DataSource; + assert(m_DataSource + && m_index < m_DataSource->GetLayersCount() + && "cannot dereference past end()"); + return Value(m_DataSource->GetLayerUnchecked(m_index)); } + +#endif // __otbOGRDataSourceWrapper_txx