[Liblas-commits] libpc: std::vector<bool> doesn't work on a lot of
compilers. Us...
liblas-commits at liblas.org
liblas-commits at liblas.org
Wed Mar 2 11:39:58 EST 2011
details: http://hg.liblas.orglibpc/rev/cb18d91a3ee5
changeset: 154:cb18d91a3ee5
user: Howard Butler <hobu.inc at gmail.com>
date: Wed Mar 02 10:39:52 2011 -0600
description:
std::vector<bool> doesn't work on a lot of compilers. Use std::vector<uint8_t>::size_type for vector indicies instead of size_t. Provide an allValid method to shortcut testing each item in the validity mask individually.
diffstat:
include/libpc/PointData.hpp | 13 ++++++++++---
src/PointData.cpp | 41 ++++++++++++++++++++++++++++++++++-------
2 files changed, 44 insertions(+), 10 deletions(-)
diffs (137 lines):
diff -r a29f4d126312 -r cb18d91a3ee5 include/libpc/PointData.hpp
--- a/include/libpc/PointData.hpp Tue Mar 01 16:21:54 2011 -0800
+++ b/include/libpc/PointData.hpp Wed Mar 02 10:39:52 2011 -0600
@@ -54,8 +54,12 @@
// collection is to be operated upon. The point index is a uint32; you can't read
// more than 4 billion points at a time.
class LIBPC_DLL PointData
+
{
+
public:
+ typedef std::vector<boost::uint8_t> valid_mask_type;
+
// note that when we make a PointData object all the fields are initialized to inactive,
// regardless of what the passed-in schema says -- this is because the field object
// represents the state within the owning object, which in this case is a completely
@@ -85,8 +89,10 @@
// "valid" means the data for the point can be used; if invalid, the point should
// be ignored or skipped. (This is done for efficiency; we don't want to have to
// modify the buffer's size just to "delete" a point.)
- bool isValid(std::size_t pointIndex) const;
- void setValid(std::size_t pointIndex, bool value=true);
+ bool isValid(valid_mask_type::size_type pointIndex) const;
+ bool allValid() const;
+ void setValid(valid_mask_type::size_type pointIndex, bool value=true);
+
// accessors to a particular field of a particular point in this buffer
template<class T> T getField(std::size_t pointIndex, std::size_t fieldIndex) const;
@@ -108,7 +114,8 @@
boost::uint8_t* m_data;
std::size_t m_pointSize;
boost::uint32_t m_numPoints;
- std::vector<bool> m_isValid; // one bool for each point
+
+ valid_mask_type m_isValid; // one byte for each point
PointData(const PointData&); // not implemented
PointData& operator=(const PointData&); // not implemented
diff -r a29f4d126312 -r cb18d91a3ee5 src/PointData.cpp
--- a/src/PointData.cpp Tue Mar 01 16:21:54 2011 -0800
+++ b/src/PointData.cpp Wed Mar 02 10:39:52 2011 -0600
@@ -36,6 +36,7 @@
#include <cassert>
#include <iostream>
+#include <numeric>
using std::endl;
using std::string;
@@ -48,13 +49,14 @@
m_schemaLayout(schemaLayout),
m_data(NULL),
m_pointSize(0),
- m_numPoints(numPoints)
+ m_numPoints(numPoints),
+ m_isValid(numPoints)
{
m_pointSize = m_schemaLayout.getByteSize();
m_data = new boost::uint8_t[m_pointSize * m_numPoints];
// the points will all be set to invalid here
- m_isValid.resize(m_numPoints);
+ m_isValid.assign(0, m_isValid.size());
return;
}
@@ -62,21 +64,36 @@
PointData::~PointData()
{
- delete[] m_data;
+ if (m_data)
+ delete[] m_data;
}
bool
PointData::isValid(std::size_t index) const
{
- return m_isValid[index];
+ return static_cast<bool>(m_isValid[index]);
}
+bool PointData::allValid() const
+{
+ // Assuming each byte is set to 1 for true and 0 for false,
+ // if the sum of all of the bytes in the mask == the size
+ // of the mask, all the data are valid. This hopefully is faster
+ // than walking all of the points individually and doing an
+ // if test
+
+ boost::uint32_t sum = std::accumulate(m_isValid.begin(), m_isValid.end(), 0);
+ if (sum == m_isValid.size())
+ return true;
+
+ return false;
+}
void
PointData::setValid(std::size_t index, bool value)
{
- m_isValid[index] = value;
+ m_isValid[index] = static_cast<bool>(value);
}
@@ -102,6 +119,7 @@
memcpy(dest, src, len);
+
setValid(destPointIndex, srcPointData.isValid(srcPointIndex));
return;
@@ -118,10 +136,19 @@
memcpy(dest, src, len * numPoints);
- for (std::size_t i=0; i<numPoints; i++)
+ if (srcPointData.allValid())
{
- setValid(destPointIndex+i, srcPointData.isValid(srcPointIndex+i));
+ m_isValid.assign(1, m_isValid.size());
}
+ else
+ {
+ for (valid_mask_type::size_type i=0; i<numPoints; i++)
+ {
+ setValid(destPointIndex+i, srcPointData.isValid(srcPointIndex+i));
+ }
+
+ }
+
return;
}
More information about the Liblas-commits
mailing list