Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into issues-888
Browse files Browse the repository at this point in the history
  • Loading branch information
abellgithub committed May 1, 2015
2 parents 697224d + c9eacca commit 77a9675
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 70 deletions.
86 changes: 18 additions & 68 deletions include/pdal/PointView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,6 @@ class PDAL_DLL PointView
inline PointId getTemp(PointId id);
void freeTemp(PointId id)
{ m_temps.push(id); }

// Awfulness to avoid exceptions in numeric cast. This was in the function
// where it's used (convertAndSet), but older g++ couldn't deal.
static bool m_ok;
};

struct PointViewLess
Expand Down Expand Up @@ -417,24 +413,17 @@ inline T PointView::getFieldAs(Dimension::Id::Enum dim,
val = 0;
break;
}
#ifdef PDAL_COMPILER_MSVC
// warning C4127: conditional expression is constant
#pragma warning(push)
#pragma warning(disable:4127)
#endif
try

if (Utils::inRange<T>(val))
{
if (std::is_same<T, double>::value)
retval = val;
else
if (std::is_integral<T>::value)
{
if (std::is_integral<T>::value == true )
retval = boost::numeric_cast<T>(lround(val));
else
retval = boost::numeric_cast<T>(val);
val = Utils::sround(val);
}

retval = static_cast<T>(val);
}
catch (boost::numeric::bad_numeric_cast& )
else
{
std::ostringstream oss;
oss << "Unable to fetch data and convert as requested: ";
Expand All @@ -443,69 +432,30 @@ inline T PointView::getFieldAs(Dimension::Id::Enum dim,
"(" << (double)val << ") -> " << Utils::typeidName<T>();
throw pdal_error(oss.str());
}

return retval;
#ifdef PDAL_COMPILER_MSVC
// warning C4127: conditional expression is constant
#pragma warning(pop)
#endif
}



template<typename T_IN, typename T_OUT>
bool PointView::convertAndSet(Dimension::Id::Enum dim, PointId idx, T_IN in)
{
// This mess, instead of just using boost::numeric_cast, is here to:
// 1) Prevent the throwing of exceptions. The entrance/exit of the try
// block seemed somewhat expensive.
// 2) Round to nearest instead of truncation without rounding before
// invoking the converter.
//
using namespace boost;

struct RangeHandler
bool success(false);

if (Utils::inRange<T_IN, T_OUT>(in))
{
void operator() (numeric::range_check_result r)
if (std::is_integral<T_OUT>::value)
{
m_ok = (r == numeric::cInRange);
in = Utils::sround(in);
}
};

T_OUT out;

typedef numeric::conversion_traits<T_OUT, T_IN> conv_traits;
typedef numeric::numeric_cast_traits<T_OUT, T_IN> cast_traits;
typedef numeric::converter<
T_OUT,
T_IN,
conv_traits,
RangeHandler,
numeric::RoundEven<T_IN>,
numeric::raw_converter<conv_traits>,
typename cast_traits::range_checking_policy>
localConverter;

#ifdef PDAL_COMPILER_MSVC
// warning C4127: conditional expression is constant
#pragma warning(push)
#pragma warning(disable:4127)
#endif
m_ok = true;
// This is an optimization.
if (std::is_same<T_IN, T_OUT>::value == true)
out = in;
else
out = localConverter::convert(in);
if (!m_ok)
return false;

#ifdef PDAL_COMPILER_MSVC
// warning C4127: conditional expression is constant
#pragma warning(pop)
#endif
const T_OUT out(static_cast<T_OUT>(in));
setFieldInternal(dim, idx, &out);
success = true;
}

setFieldInternal(dim, idx, (void *)&out);
return true;
return success;
}


Expand Down
24 changes: 24 additions & 0 deletions include/pdal/Utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,30 @@ namespace Utils
out.rdbuf(redir.m_buf);
redir.m_out->close();
}

// Determine whether a value of a given input type may be safely
// statically casted to the given output type without over/underflow. If
// the output type is integral, inRange() will determine whether the
// rounded input value, rather than truncated, may be safely converted.
template<typename T_OUT>
bool inRange(double in)
{
if (std::is_integral<T_OUT>::value)
{
in = sround(in);
}

return std::is_same<double, T_OUT>::value ||
(in >= static_cast<double>(std::numeric_limits<T_OUT>::lowest()) &&
in <= static_cast<double>(std::numeric_limits<T_OUT>::max()));
}

template<typename T_IN, typename T_OUT>
bool inRange(T_IN in)
{
return std::is_same<T_IN, T_OUT>::value ||
inRange<T_OUT>(static_cast<double>(in));
}
};

} // namespace pdal
Expand Down
2 changes: 0 additions & 2 deletions src/PointView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
namespace pdal
{

PDAL_DLL bool PointView::m_ok;

PointViewIter PointView::begin()
{
return PointViewIter(this, 0);
Expand Down

0 comments on commit 77a9675

Please sign in to comment.