[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