Commit 6e850352 authored by Luc Hermitte's avatar Luc Hermitte

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

parent 3c24ab6a
......@@ -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)
......
......@@ -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
......
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment