Skip to content
Snippets Groups Projects
Commit 6e850352 authored by Luc Hermitte's avatar Luc Hermitte
Browse files

ENH: OTB-134/OGR: mayers iteration + code moved to inline file

parent 3c24ab6a
Branches
Tags
No related merge requests found
...@@ -19,7 +19,9 @@ ...@@ -19,7 +19,9 @@
#include "otbOGRDataSourceWrapper.h" #include "otbOGRDataSourceWrapper.h"
// standard includes // standard includes
#include <cassert> #include <cassert>
#include <numeric>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/foreach.hpp>
// ITK includes // ITK includes
#include "itkMacro.h" // itkExceptionMacro #include "itkMacro.h" // itkExceptionMacro
#include "itkMetaDataObject.h" #include "itkMetaDataObject.h"
...@@ -125,15 +127,11 @@ otb::ogr::DataSource::New(OGRDataSource * source) ...@@ -125,15 +127,11 @@ otb::ogr::DataSource::New(OGRDataSource * source)
otb::ogr::DataSource::const_iterator otb::ogr::DataSource::cbegin() const otb::ogr::DataSource::const_iterator otb::ogr::DataSource::cbegin() const
{ {
return const_iterator(*this, 0); return const_iterator(*this, 0);
// assert(!"not-ready");
// return const_iterator();
} }
otb::ogr::DataSource::const_iterator otb::ogr::DataSource::cend() const otb::ogr::DataSource::const_iterator otb::ogr::DataSource::cend() const
{ {
return const_iterator(*this, GetLayersCount()); return const_iterator(*this, GetLayersCount());
// assert(!"not-ready");
// return const_iterator();
} }
otb::ogr::DataSource::iterator otb::ogr::DataSource::begin() otb::ogr::DataSource::iterator otb::ogr::DataSource::begin()
...@@ -282,7 +280,7 @@ namespace { // Anonymous namespace ...@@ -282,7 +280,7 @@ namespace { // Anonymous namespace
{ {
AccuLayersSizes(bool doForceComputation) AccuLayersSizes(bool doForceComputation)
: m_doForceComputation(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); const int loc_size = layer.GetFeatureCount(m_doForceComputation);
return loc_size < 0 ? loc_size : loc_size+accumulated; return loc_size < 0 ? loc_size : loc_size+accumulated;
...@@ -294,7 +292,7 @@ namespace { // Anonymous namespace ...@@ -294,7 +292,7 @@ namespace { // Anonymous namespace
int otb::ogr::DataSource::Size(bool doForceComputation) const 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( ...@@ -306,7 +304,10 @@ void otb::ogr::DataSource::PrintSelf(
std::ostream& os, itk::Indent indent) const std::ostream& os, itk::Indent indent) const
{ {
assert(m_DataSource && "Datasource not initialized"); 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) /*virtual*/ void otb::ogr::DataSource::Graft(const itk::DataObject * data)
......
...@@ -248,9 +248,10 @@ public: ...@@ -248,9 +248,10 @@ public:
* \see http://www.boost.org/doc/libs/1_49_0/libs/iterator/doc/iterator_facade.html#tutorial-example * \see http://www.boost.org/doc/libs/1_49_0/libs/iterator/doc/iterator_facade.html#tutorial-example
*/ */
template <class Value> class layer_iter 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 {}; struct enabler {};
/** Const-synchronized type of the \c DataSource container. /** Const-synchronized type of the \c DataSource container.
* \internal * \internal
* The definition of a new series of functions \c boost::copy_const, * The definition of a new series of functions \c boost::copy_const,
...@@ -264,42 +265,25 @@ public: ...@@ -264,42 +265,25 @@ public:
* So here is the hard-coded result of what \c boost::copy_const would have * So here is the hard-coded result of what \c boost::copy_const would have
* given in order to avoid any licensing issue. * given in order to avoid any licensing issue.
*/ */
typedef typename boost::mpl::if_ typedef typename boost::mpl::if_ <boost::is_const<Value> , otb::ogr::DataSource const , otb::ogr::DataSource >::type
<boost::is_const<Value> container_type;
, otb::ogr::DataSource const
, otb::ogr::DataSource
>::type container_type;
public: public:
layer_iter(container_type & datasource, size_t index) layer_iter(container_type & datasource, size_t index);
: m_DataSource(&datasource), m_index(index) {} layer_iter(); ;
layer_iter()
: m_DataSource(0), m_index(0) {}
template <class OtherValue> layer_iter( template <class OtherValue> layer_iter(
layer_iter<OtherValue> const& other, layer_iter<OtherValue> const& other,
typename boost::enable_if<boost::is_convertible<OtherValue*,Value*> typename boost::enable_if<boost::is_convertible<OtherValue*,Value*>
, enabler , enabler
>::type = enabler() >::type = enabler()
) );
: m_DataSource(other.m_DataSource), m_index(other.m_index)
{}
private: private:
friend class boost::iterator_core_access; friend class boost::iterator_core_access;
template <class> friend class layer_iter; template <class> friend class layer_iter;
template <class OtherValue> bool equal(layer_iter<OtherValue> const& other) const template <class OtherValue> bool equal(layer_iter<OtherValue> const& other) const;
{ void increment();
return m_DataSource == other.m_DataSource && other.m_index == m_index; Value dereference() const;
}
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);
}
container_type * m_DataSource; container_type * m_DataSource;
size_t m_index; size_t m_index;
...@@ -317,29 +301,6 @@ public: ...@@ -317,29 +301,6 @@ public:
iterator end (); 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. /** Returns the number of elements in the Data Source.
* \param[in] doForceComputation indicates whether the size shall be * \param[in] doForceComputation indicates whether the size shall be
* computed on each layer even so it's expensive to do so. * computed on each layer even so it's expensive to do so.
...@@ -538,8 +499,7 @@ public: ...@@ -538,8 +499,7 @@ public:
* boolean expression to be used in \c if tests. * boolean expression to be used in \c if tests.
* \see <em>Imperfect C++</em>, Matthew Wilson, Addisson-Welsey, par 24.6 * \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; return m_DataSource ? &boolean::i : 0;
} }
...@@ -587,6 +547,7 @@ protected: ...@@ -587,6 +547,7 @@ protected:
* \post the \c OGRDataSource owned is released (if not null). * \post the \c OGRDataSource owned is released (if not null).
*/ */
virtual ~DataSource(); virtual ~DataSource();
/** Prints self into stream. */ /** Prints self into stream. */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
...@@ -602,6 +563,9 @@ private: ...@@ -602,6 +563,9 @@ private:
* OGRDataSource::GetLayer(). * OGRDataSource::GetLayer().
*/ */
OGRLayer* GetLayerUnchecked(size_t i); 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(const Self&); //purposely not implemented
DataSource& operator =(const Self&); //purposely not implemented DataSource& operator =(const Self&); //purposely not implemented
......
...@@ -32,11 +32,18 @@ ...@@ -32,11 +32,18 @@
#include "ogrsf_frmts.h" // OGRDataSource & OGRLayer #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 inline
otb::ogr::Layer otb::ogr::DataSource::GetLayer(size_t i) 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 ...@@ -65,47 +72,59 @@ otb::ogr::Layer const otb::ogr::DataSource::GetLayerChecked(size_t i) const
return const_cast <DataSource*>(this)->GetLayerChecked(i); return const_cast <DataSource*>(this)->GetLayerChecked(i);
} }
template <class Functor, typename V>
inline 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"); return const_cast <DataSource*>(this)->GetLayerUnchecked(i);
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;
} }
template <class Functor> /*===========================================================================*/
inline /*====================[ otb::ogr::DataSource/iterators ]=====================*/
void otb::ogr::DataSource::ForEachLayer(Functor f) const /*===========================================================================*/
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"); return m_DataSource == other.m_DataSource && other.m_index == m_index;
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);
}
} }
#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 template <class Value>
OGRDataSource & otb::ogr::DataSource::ogr() Value otb::ogr::DataSource::layer_iter<Value>::dereference() const
{ {
assert(m_DataSource && "OGRDataSource not initialized"); assert(m_DataSource
return *m_DataSource; && m_index < m_DataSource->GetLayersCount()
&& "cannot dereference past end()");
return Value(m_DataSource->GetLayerUnchecked(m_index));
} }
#endif // __otbOGRDataSourceWrapper_txx
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment