$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r78335 - in trunk: boost/polygon boost/polygon/detail libs/polygon/test
From: sydorchuk.andriy_at_[hidden]
Date: 2012-05-05 10:29:12
Author: asydorchuk
Date: 2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
New Revision: 78335
URL: http://svn.boost.org/trac/boost/changeset/78335
Log:
Merging Polygon with Voronoi library.
Adding Boost.Polygon segment concept.
Adding Voronoi tests.
Adding Boost.Polygon segment concept/data/traits tests.
Added:
   trunk/boost/polygon/detail/voronoi_ctypes.hpp   (contents, props changed)
   trunk/boost/polygon/detail/voronoi_predicates.hpp   (contents, props changed)
   trunk/boost/polygon/detail/voronoi_robust_fpt.hpp   (contents, props changed)
   trunk/boost/polygon/detail/voronoi_structures.hpp   (contents, props changed)
   trunk/boost/polygon/segment_concept.hpp   (contents, props changed)
   trunk/boost/polygon/segment_data.hpp   (contents, props changed)
   trunk/boost/polygon/segment_traits.hpp   (contents, props changed)
   trunk/boost/polygon/voronoi.hpp   (contents, props changed)
   trunk/boost/polygon/voronoi_builder.hpp   (contents, props changed)
   trunk/boost/polygon/voronoi_diagram.hpp   (contents, props changed)
   trunk/boost/polygon/voronoi_utils.hpp   (contents, props changed)
   trunk/libs/polygon/test/polygon_segment_test.cpp   (contents, props changed)
   trunk/libs/polygon/test/voronoi_builder_test.cpp   (contents, props changed)
   trunk/libs/polygon/test/voronoi_ctypes_test.cpp   (contents, props changed)
   trunk/libs/polygon/test/voronoi_predicates_test.cpp   (contents, props changed)
   trunk/libs/polygon/test/voronoi_robust_fpt_test.cpp   (contents, props changed)
   trunk/libs/polygon/test/voronoi_structures_test.cpp   (contents, props changed)
   trunk/libs/polygon/test/voronoi_test_helper.hpp   (contents, props changed)
Removed:
   trunk/boost/polygon/directed_line_segment_concept.hpp
   trunk/boost/polygon/directed_line_segment_data.hpp
   trunk/boost/polygon/directed_line_segment_set_data.hpp
   trunk/boost/polygon/directed_line_segment_traits.hpp
Text files modified: 
   trunk/boost/polygon/interval_concept.hpp        |   252 +++++++++++++++++++++++---------------- 
   trunk/boost/polygon/point_3d_concept.hpp        |    28 ++--                                    
   trunk/boost/polygon/point_concept.hpp           |   199 +++++++++++++++++--------------         
   trunk/boost/polygon/polygon.hpp                 |     7                                         
   trunk/boost/polygon/polygon_90_set_concept.hpp  |    17 +-                                      
   trunk/boost/polygon/polygon_traits.hpp          |     2                                         
   trunk/boost/polygon/rectangle_concept.hpp       |   214 ++++++++++++++++----------------        
   trunk/libs/polygon/test/Jamfile.v2              |    14 ++                                      
   trunk/libs/polygon/test/gtl_boost_unit_test.cpp |    17 +-                                      
   9 files changed, 411 insertions(+), 339 deletions(-)
Added: trunk/boost/polygon/detail/voronoi_ctypes.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/detail/voronoi_ctypes.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,713 @@
+// Boost.Polygon library detail/voronoi_ctypes.hpp header file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POLYGON_DETAIL_VORONOI_CTYPES
+#define BOOST_POLYGON_DETAIL_VORONOI_CTYPES
+
+#include <cmath>
+#include <cstring>
+
+#include <boost/cstdint.hpp>
+
+namespace boost {
+namespace polygon {
+namespace detail {
+
+typedef boost::int32_t int32;
+typedef boost::int64_t int64;
+typedef boost::uint32_t uint32;
+typedef boost::uint64_t uint64;
+typedef double fpt64;
+
+// If two floating-point numbers in the same format are ordered (x < y),
+// then they are ordered the same way when their bits are reinterpreted as
+// sign-magnitude integers. Values are considered to be almost equal if
+// their integer bits reinterpretations differ in not more than maxUlps units.
+template <typename _fpt>
+struct ulp_comparison;
+
+template <>
+struct ulp_comparison<fpt64> {
+  enum Result {
+    LESS = -1,
+    EQUAL = 0,
+    MORE = 1
+  };
+
+  Result operator()(fpt64 a, fpt64 b, unsigned int maxUlps) const {
+    uint64 ll_a, ll_b;
+
+    // Reinterpret double bits as 64-bit signed integer.
+    memcpy(&ll_a, &a, sizeof(fpt64));
+    memcpy(&ll_b, &b, sizeof(fpt64));
+
+    // Positive 0.0 is integer zero. Negative 0.0 is 0x8000000000000000.
+    // Map negative zero to an integer zero representation - making it
+    // identical to positive zero - the smallest negative number is
+    // represented by negative one, and downwards from there.
+    if (ll_a < 0x8000000000000000ULL)
+      ll_a = 0x8000000000000000ULL - ll_a;
+    if (ll_b < 0x8000000000000000ULL)
+      ll_b = 0x8000000000000000ULL - ll_b;
+
+    // Compare 64-bit signed integer representations of input values.
+    // Difference in 1 Ulp is equivalent to a relative error of between
+    // 1/4,000,000,000,000,000 and 1/8,000,000,000,000,000.
+    if (ll_a > ll_b)
+      return (ll_a - ll_b <= maxUlps) ? EQUAL : LESS;
+    return (ll_b - ll_a <= maxUlps) ? EQUAL : MORE;
+  }
+};
+
+// Manages exponent of the floating-point value.
+template <typename _fpt>
+struct fpt_exponent_accessor;
+
+template <>
+class fpt_exponent_accessor<fpt64> {
+public:
+  static const int64 kExponentMask;
+  static const int64 kSignedMantissaMask;
+  static const int64 kMinExponent;
+  static const int64 kMaxExponent;
+  static const int64 kMaxSignificantExpDif;
+
+  static int64 set_exponent(fpt64& value, int64 exponent) {
+    int64 bits;
+    memcpy(&bits, &value, sizeof(fpt64));
+    int64 exp = ((bits & kExponentMask) >> 52) - 1023;
+    if (exp == exponent)
+      return exp;
+    bits = (bits & kSignedMantissaMask) | ((exponent + 1023) << 52);
+    memcpy(&value, &bits, sizeof(fpt64));
+    return exp;
+  }
+};
+
+const int64 fpt_exponent_accessor<fpt64>::kExponentMask =
+  0x7ff0000000000000LL;
+const int64 fpt_exponent_accessor<fpt64>::kSignedMantissaMask =
+  0x800fffffffffffffLL;
+const int64 fpt_exponent_accessor<fpt64>::kMinExponent = -1023LL;
+const int64 fpt_exponent_accessor<fpt64>::kMaxExponent = 1024LL;
+const int64 fpt_exponent_accessor<fpt64>::kMaxSignificantExpDif = 54;
+
+// Floating point type wrapper. Allows to extend exponent boundaries to the
+// 64 bit integer range. This class does not handle division by zero, subnormal
+// numbers or NaNs.
+template <typename _fpt>
+class extended_exponent_fpt {
+public:
+  typedef _fpt fpt_type;
+  typedef int64 exp_type;
+  typedef fpt_exponent_accessor<fpt_type> fea;
+
+  explicit extended_exponent_fpt(fpt_type value) {
+    if (value == 0.0) {
+      exponent_ = 0;
+      value_ = 0.0;
+    } else {
+      exponent_ = fea::set_exponent(value, 0);
+      value_ = value;
+    }
+  }
+
+  extended_exponent_fpt(fpt_type value, exp_type exponent) {
+    if (value == 0.0) {
+      exponent_ = 0;
+      value_ = 0.0;
+    } else {
+      exponent_ = fea::set_exponent(value, 0) + exponent;
+      value_ = value;
+    }
+  }
+
+  bool is_pos() const {
+    return value_ > 0;
+  }
+
+  bool is_neg() const {
+    return value_ < 0;
+  }
+
+  bool is_zero() const {
+    return value_ == 0;
+  }
+
+  extended_exponent_fpt operator-() const {
+    return extended_exponent_fpt(-value_, exponent_);
+  }
+
+  extended_exponent_fpt operator+(const extended_exponent_fpt& that) const {
+    if (this->value_ == 0.0 ||
+      that.exponent_ > this->exponent_ + fea::kMaxSignificantExpDif) {
+      return that;
+    }
+    if (that.value_ == 0.0 ||
+      this->exponent_ > that.exponent_ + fea::kMaxSignificantExpDif) {
+      return *this;
+    }
+    if (this->exponent_ >= that.exponent_) {
+      exp_type exp_dif = this->exponent_ - that.exponent_;
+      fpt_type value = this->value_;
+      fea::set_exponent(value, exp_dif);
+      value += that.value_;
+      return extended_exponent_fpt(value, that.exponent_);
+    } else {
+      exp_type exp_dif = that.exponent_ - this->exponent_;
+      fpt_type value = that.value_;
+      fea::set_exponent(value, exp_dif);
+      value += this->value_;
+      return extended_exponent_fpt(value, this->exponent_);
+    }
+  }
+
+  extended_exponent_fpt operator-(const extended_exponent_fpt& that) const {
+    if (this->value_ == 0.0 ||
+      that.exponent_ > this->exponent_ + fea::kMaxSignificantExpDif) {
+      return extended_exponent_fpt(-that.value_, that.exponent_);
+    }
+    if (that.value_ == 0.0 ||
+      this->exponent_ > that.exponent_ + fea::kMaxSignificantExpDif) {
+      return *this;
+    }
+    if (this->exponent_ >= that.exponent_) {
+      exp_type exp_dif = this->exponent_ - that.exponent_;
+      fpt_type value = this->value_;
+      fea::set_exponent(value, exp_dif);
+      value -= that.value_;
+      return extended_exponent_fpt(value, that.exponent_);
+    } else {
+      exp_type exp_dif = that.exponent_ - this->exponent_;
+      fpt_type value = -that.value_;
+      fea::set_exponent(value, exp_dif);
+      value += this->value_;
+      return extended_exponent_fpt(value, this->exponent_);
+    }
+  }
+
+  extended_exponent_fpt operator*(const extended_exponent_fpt& that) const {
+    fpt_type value = this->value_ * that.value_;
+    exp_type exponent = this->exponent_ + that.exponent_;
+    return extended_exponent_fpt(value, exponent);
+  }
+
+  extended_exponent_fpt operator/(const extended_exponent_fpt& that) const {
+    fpt_type value = this->value_ / that.value_;
+    exp_type exponent = this->exponent_ - that.exponent_;
+    return extended_exponent_fpt(value, exponent);
+  }
+
+  extended_exponent_fpt& operator+=(const extended_exponent_fpt& that) {
+    return *this = *this + that;
+  }
+
+  extended_exponent_fpt& operator-=(const extended_exponent_fpt& that) {
+    return *this = *this - that;
+  }
+
+  extended_exponent_fpt& operator*=(const extended_exponent_fpt& that) {
+    return *this = *this * that;
+  }
+
+  extended_exponent_fpt& operator/=(const extended_exponent_fpt& that) {
+    return *this = *this / that;
+  }
+
+  extended_exponent_fpt sqrt() const {
+    fpt_type val = value_;
+    exp_type exp = exponent_;
+    if (exp & 1) {
+      val *= 2.0;
+      --exp;
+    }
+    return extended_exponent_fpt(std::sqrt(val), exp >> 1);
+  }
+
+  fpt_type d() const {
+    fpt_type ret_val = value_;
+    exp_type exp = exponent_;
+    if (ret_val == 0.0)
+      return ret_val;
+    if (exp >= fea::kMaxExponent) {
+      ret_val = 1.0;
+      exp = fea::kMaxExponent;
+    } else if (exp <= fea::kMinExponent) {
+      ret_val = 1.0;
+      exp = fea::kMinExponent;
+    }
+    fea::set_exponent(ret_val, exp);
+    return ret_val;
+  }
+
+private:
+  fpt_type value_;
+  exp_type exponent_;
+};
+typedef extended_exponent_fpt<double> efpt64;
+
+template <typename _fpt>
+extended_exponent_fpt<_fpt> get_sqrt(const extended_exponent_fpt<_fpt>& that) {
+  return that.sqrt();
+}
+
+template <typename _fpt>
+bool is_pos(const extended_exponent_fpt<_fpt>& that) {
+  return that.is_pos();
+}
+
+template <typename _fpt>
+bool is_neg(const extended_exponent_fpt<_fpt>& that) {
+  return that.is_neg();
+}
+
+template <typename _fpt>
+bool is_zero(const extended_exponent_fpt<_fpt>& that) {
+  return that.is_zero();
+}
+
+// Very efficient stack allocated big integer class.
+// Supports next set of arithmetic operations: +, -, *.
+template<size_t N>
+class extended_int {
+public:
+  static const uint64 kUInt64LowMask;
+  static const uint64 kUInt64HighMask;
+
+  extended_int() {}
+
+  extended_int(int32 that) {
+    if (that > 0) {
+      this->chunks_[0] = that;
+      this->count_ = 1;
+    } else if (that < 0) {
+      this->chunks_[0] = -that;
+      this->count_ = -1;
+    } else {
+      this->count_ = 0;
+    }
+  }
+
+  extended_int(int64 that) {
+    if (that > 0) {
+      this->chunks_[0] = static_cast<uint32>(that & kUInt64LowMask);
+      this->chunks_[1] = that >> 32;
+      this->count_ = this->chunks_[1] ? 2 : 1;
+    } else if (that < 0) {
+      that = -that;
+      this->chunks_[0] = static_cast<uint32>(that & kUInt64LowMask);
+      this->chunks_[1] = that >> 32;
+      this->count_ = this->chunks_[1] ? -2 : -1;
+    } else {
+      this->count_ = 0;
+    }
+  }
+
+  extended_int(const std::vector<uint32>& chunks, bool plus = true) {
+    this->count_ = static_cast<int32>((std::min)(N, chunks.size()));
+    for (int i = 0; i < this->count_; ++i)
+      this->chunks_[i] = chunks[chunks.size() - i - 1];
+    if (!plus)
+      this->count_ = -this->count_;
+  }
+
+  template <size_t M>
+  extended_int(const extended_int<M>& that) {
+    if (that.size() > N) return;
+    this->count_ = that.count();
+    memcpy(this->chunks_, that.chunks(), that.size() * sizeof(uint32));
+  }
+
+  extended_int& operator=(int32 that) {
+    if (that > 0) {
+      this->chunks_[0] = that;
+      this->count_ = 1;
+    } else if (that < 0) {
+      this->chunks_[0] = -that;
+      this->count_ = -1;
+    } else {
+      this->count_ = 0;
+    }
+    return *this;
+  }
+
+  extended_int& operator=(int64 that) {
+    if (that > 0) {
+      this->chunks_[0] = static_cast<uint32>(that & kUInt64LowMask);
+      this->chunks_[1] = that >> 32;
+      this->count_ = this->chunks_[1] ? 2 : 1;
+    } else if (that < 0) {
+      that = -that;
+      this->chunks_[0] = static_cast<uint32>(that & kUInt64LowMask);
+      this->chunks_[1] = that >> 32;
+      this->count_ = this->chunks_[1] ? -2 : -1;
+    } else {
+      this->count_ = 0;
+    }
+    return *this;
+  }
+
+  template <size_t M>
+  extended_int& operator=(const extended_int<M>& that) {
+    size_t mx = (std::max)(N, that.size());
+    this->count_ = that.count();
+    memcpy(this->chunks_, that.chunks(), mx * sizeof(uint32));
+    return *this;
+  }
+
+  bool is_pos() const {
+    return this->count_ > 0;
+  }
+
+  bool is_neg() const {
+    return this->count_ < 0;
+  }
+
+  bool is_zero() const {
+    return this->count_ == 0;
+  }
+
+  template <size_t M>
+  bool operator==(const extended_int<M>& that) const {
+    if (this->count_ != that.count())
+      return false;
+    for (size_t i = 0; i < this->size(); ++i)
+      if (this->chunks_[i] != that.chunks()[i])
+        return false;
+    return true;
+  }
+
+  template <size_t M>
+  bool operator!=(const extended_int<M>& that) const {
+    return !(*this == that);
+  }
+
+  template <size_t M>
+  bool operator<(const extended_int<M>& that) const {
+    if (this->count_ != that.count())
+      return this->count_ < that.count();
+    size_t i = this->size();
+    if (!i)
+      return false;
+    do {
+      --i;
+      if (this->chunks_[i] != that.chunks()[i])
+        return (this->chunks_[i] < that.chunks()[i]) ^ (this->count_ < 0);
+    } while (i);
+    return false;
+  }
+
+  template <size_t M>
+  bool operator>(const extended_int<M>& that) const {
+    return that < *this;
+  }
+
+  template <size_t M>
+  bool operator<=(const extended_int<M>& that) const {
+    return !(that < *this);
+  }
+
+  template <size_t M>
+  bool operator>=(const extended_int<M>& that) const {
+    return !(*this < that);
+  }
+
+  extended_int operator-() const {
+    extended_int ret_val = *this;
+    ret_val.neg();
+    return ret_val;
+  }
+
+  void neg() {
+    this->count_ = -this->count_;
+  }
+
+  template <size_t M>
+  extended_int<(N>M?N:M)> operator+(const extended_int<M>& that) const {
+    extended_int<(N>M?N:M)> ret_val;
+    ret_val.add(*this, that);
+    return ret_val;
+  }
+
+  template <size_t N1, size_t N2>
+  void add(const extended_int<N1>& e1, const extended_int<N2>& e2) {
+    if (!e1.count()) {
+      *this = e2;
+      return;
+    }
+    if (!e2.count()) {
+      *this = e1;
+      return;
+    }
+    if ((e1.count() > 0) ^ (e2.count() > 0)) {
+      dif(e1.chunks(), e1.size(), e2.chunks(), e2.size());
+    } else {
+      add(e1.chunks(), e1.size(), e2.chunks(), e2.size());
+    }
+    if (e1.count() < 0)
+      this->count_ = -this->count_;
+  }
+
+  template <size_t M>
+  extended_int<(N>M?N:M)> operator-(const extended_int<M>& that) const {
+    extended_int<(N>M?N:M)> ret_val;
+    ret_val.dif(*this, that);
+    return ret_val;
+  }
+
+  template <size_t N1, size_t N2>
+  void dif(const extended_int<N1>& e1, const extended_int<N2> &e2) {
+    if (!e1.count()) {
+      *this = e2;
+      this->count_ = -this->count_;
+      return;
+    }
+    if (!e2.count()) {
+      *this = e1;
+      return;
+    }
+    if ((e1.count() > 0) ^ (e2.count() > 0)) {
+      add(e1.chunks(), e1.size(), e2.chunks(), e2.size());
+    } else {
+      dif(e1.chunks(), e1.size(), e2.chunks(), e2.size());
+    }
+    if (e1.count() < 0)
+      this->count_ = -this->count_;
+  }
+
+  extended_int<N> operator*(int32 that) const {
+    extended_int<N> temp(that);
+    return (*this) * temp;
+  }
+
+  extended_int<N> operator*(int64 that) const {
+    extended_int<N> temp(that);
+    return (*this) * temp;
+  }
+
+  template <size_t M>
+  extended_int<(N>M?N:M)> operator*(const extended_int<M>& that) const {
+    extended_int<(N>M?N:M)> ret_val;
+    ret_val.mul(*this, that);
+    return ret_val;
+  }
+
+  template <size_t N1, size_t N2>
+  void mul(const extended_int<N1>& e1, const extended_int<N2>& e2) {
+    if (!e1.count() || !e2.count()) {
+      this->count_ = 0;
+      return;
+    }
+    mul(e1.chunks(), e1.size(), e2.chunks(), e2.size());
+    if ((e1.count() > 0) ^ (e2.count() > 0))
+      this->count_ = -this->count_;
+  }
+
+  const uint32* chunks() const {
+    return chunks_;
+  }
+
+  int32 count() const {
+    return count_;
+  }
+
+  size_t size() const {
+    return (std::abs)(count_);
+  }
+
+  std::pair<fpt64, int64> p() const {
+    std::pair<fpt64, int64> ret_val(0, 0);
+    size_t sz = this->size();
+    if (!sz) {
+      return ret_val;
+    } else {
+      if (sz == 1) {
+        ret_val.first = static_cast<fpt64>(this->chunks_[0]);
+      } else if (sz == 2) {
+        ret_val.first = static_cast<fpt64>(this->chunks_[1]) *
+                        static_cast<fpt64>(0x100000000LL) +
+                        static_cast<fpt64>(this->chunks_[0]);
+      } else {
+        for (size_t i = 1; i <= 3; ++i) {
+          ret_val.first *= static_cast<fpt64>(0x100000000LL);
+          ret_val.first += static_cast<fpt64>(this->chunks_[sz - i]);
+        }
+        ret_val.second = (sz - 3) << 5;
+      }
+    }
+    if (this->count_ < 0)
+      ret_val.first = -ret_val.first;
+    return ret_val;
+  }
+
+  fpt64 d() const {
+    std::pair<fpt64, int64> p = this->p();
+    extended_exponent_fpt<fpt64> efpt(p.first, p.second);
+    return efpt.d();
+  }
+
+private:
+  void add(const uint32* c1, size_t sz1, const uint32* c2, size_t sz2) {
+    if (sz1 < sz2) {
+      add(c2, sz2, c1, sz1);
+      return;
+    }
+    this->count_ = sz1;
+    uint64 temp = 0;
+    for (size_t i = 0; i < sz2; ++i) {
+      temp += static_cast<uint64>(c1[i]) + static_cast<uint64>(c2[i]);
+      this->chunks_[i] = static_cast<uint32>(temp & kUInt64LowMask);
+      temp >>= 32;
+    }
+    for (size_t i = sz2; i < sz1; ++i) {
+      temp += static_cast<uint64>(c1[i]);
+      this->chunks_[i] = static_cast<uint32>(temp & kUInt64LowMask);
+      temp >>= 32;
+    }
+    if (temp && (this->count_ != N)) {
+      this->chunks_[this->count_] = static_cast<uint32>(temp & kUInt64LowMask);
+      ++this->count_;
+    }
+  }
+
+  void dif(const uint32* c1, size_t sz1,
+           const uint32* c2, size_t sz2, bool rec = false) {
+    if (sz1 < sz2) {
+      dif(c2, sz2, c1, sz1, true);
+      this->count_ = -this->count_;
+      return;
+    } else if ((sz1 == sz2) && !rec) {
+      do {
+        --sz1;
+        if (c1[sz1] < c2[sz1]) {
+          ++sz1;
+          dif(c2, sz1, c1, sz1, true);
+          this->count_ = -this->count_;
+          return;
+        } else if (c1[sz1] > c2[sz1]) {
+          ++sz1;
+          break;
+        }
+      } while (sz1);
+      if (!sz1) {
+        this->count_ = 0;
+        return;
+      }
+      sz2 = sz1;
+    }
+    this->count_ = sz1-1;
+    bool flag = false;
+    for (size_t i = 0; i < sz2; ++i) {
+      this->chunks_[i] = c1[i] - c2[i] - (flag?1:0);
+      flag = (c1[i] < c2[i]) || ((c1[i] == c2[i]) && flag);
+    }
+    for (size_t i = sz2; i < sz1; ++i) {
+      this->chunks_[i] = c1[i] - (flag?1:0);
+      flag = !c1[i] && flag;
+    }
+    if (this->chunks_[this->count_])
+      ++this->count_;
+  }
+
+  void mul(const uint32* c1, size_t sz1, const uint32* c2, size_t sz2) {
+    uint64 cur = 0, nxt, tmp;
+    this->count_ = static_cast<int32>((std::min)(N, sz1 + sz2 - 1));
+    for (size_t shift = 0; shift < static_cast<size_t>(this->count_);
+         ++shift) {
+      nxt = 0;
+      for (size_t first = 0; first <= shift; ++first) {
+        if (first >= sz1)
+          break;
+        size_t second = shift - first;
+        if (second >= sz2)
+          continue;
+        tmp = static_cast<uint64>(c1[first]) * static_cast<uint64>(c2[second]);
+        cur += tmp & kUInt64LowMask;
+        nxt += tmp >> 32;
+      }
+      this->chunks_[shift] = static_cast<uint32>(cur & kUInt64LowMask);
+      cur = nxt + (cur >> 32);
+    }
+    if (cur && (this->count_ != N)) {
+      this->chunks_[this->count_] = static_cast<uint32>(cur & kUInt64LowMask);
+      ++this->count_;
+    }
+  }
+
+  uint32 chunks_[N];
+  int32 count_;
+};
+
+template <size_t N>
+const uint64 extended_int<N>::kUInt64LowMask = 0x00000000ffffffffULL;
+template <size_t N>
+const uint64 extended_int<N>::kUInt64HighMask = 0xffffffff00000000ULL;
+
+template <size_t N>
+bool is_pos(const extended_int<N>& that) {
+  return that.count() > 0;
+}
+
+template <size_t N>
+bool is_neg(const extended_int<N>& that) {
+  return that.count() < 0;
+}
+
+template <size_t N>
+bool is_zero(const extended_int<N>& that) {
+  return !that.count();
+}
+
+struct type_converter_fpt {
+  template <typename T>
+  fpt64 operator()(const T& that) const {
+    return static_cast<fpt64>(that);
+  }
+
+  template <size_t N>
+  fpt64 operator()(const extended_int<N>& that) const {
+    return that.d();
+  }
+
+  fpt64 operator()(const extended_exponent_fpt<fpt64>& that) const {
+    return that.d();
+  }
+};
+
+struct type_converter_efpt {
+  template <size_t N>
+  extended_exponent_fpt<fpt64> operator()(const extended_int<N>& that) const {
+    std::pair<fpt64, int64> p = that.p();
+    return extended_exponent_fpt<fpt64>(p.first, p.second);
+  }
+};
+
+// Voronoi coordinate type traits make it possible to extend algorithm
+// input coordinate range to any user provided integer type and algorithm
+// output coordinate range to any ieee-754 like floating point type.
+template <typename T>
+struct voronoi_ctype_traits;
+
+template <>
+struct voronoi_ctype_traits<int32> {
+  typedef int32 int_type;
+  typedef int64 int_x2_type;
+  typedef uint64 uint_x2_type;
+  typedef extended_int<64> big_int_type;
+  typedef fpt64 fpt_type;
+  typedef extended_exponent_fpt<fpt_type> efpt_type;
+  typedef ulp_comparison<fpt_type> ulp_cmp_type;
+  typedef type_converter_fpt to_fpt_converter_type;
+  typedef type_converter_efpt to_efpt_converter_type;
+};
+}  // detail
+}  // polygon
+}  // boost
+
+#endif  // BOOST_POLYGON_DETAIL_VORONOI_CTYPES
Added: trunk/boost/polygon/detail/voronoi_predicates.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/detail/voronoi_predicates.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,1440 @@
+// Boost.Polygon library detail/voronoi_predicates.hpp header file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POLYGON_DETAIL_VORONOI_PREDICATES
+#define BOOST_POLYGON_DETAIL_VORONOI_PREDICATES
+
+#include "voronoi_robust_fpt.hpp"
+
+namespace boost {
+namespace polygon {
+namespace detail {
+
+// Predicate utilities. Operates with the coordinate types that could
+// be converted to the 32-bit signed integer without precision loss.
+template <typename CTYPE_TRAITS>
+class voronoi_predicates {
+public:
+  typedef typename CTYPE_TRAITS::int_type int_type;
+  typedef typename CTYPE_TRAITS::int_x2_type int_x2_type;
+  typedef typename CTYPE_TRAITS::uint_x2_type uint_x2_type;
+  typedef typename CTYPE_TRAITS::big_int_type big_int_type;
+  typedef typename CTYPE_TRAITS::fpt_type fpt_type;
+  typedef typename CTYPE_TRAITS::efpt_type efpt_type;
+  typedef typename CTYPE_TRAITS::ulp_cmp_type ulp_cmp_type;
+  typedef typename CTYPE_TRAITS::to_fpt_converter_type to_fpt_converter;
+  typedef typename CTYPE_TRAITS::to_efpt_converter_type to_efpt_converter;
+
+  enum {
+    ULPS = 64,
+    ULPSx2 = 128
+  };
+
+  template <typename Point>
+  static bool is_vertical(const Point &point1, const Point &point2) {
+    return point1.x() == point2.x();
+  }
+
+  template <typename Site>
+  static bool is_vertical(const Site &site) {
+    return is_vertical(site.point0(), site.point1());
+  }
+
+  // Compute robust cross_product: a1 * b2 - b1 * a2.
+  // It was mathematically proven that the result is correct
+  // with epsilon relative error equal to 1EPS.
+  static fpt_type robust_cross_product(int_x2_type a1_,
+                                       int_x2_type b1_,
+                                       int_x2_type a2_,
+                                       int_x2_type b2_) {
+    static to_fpt_converter to_fpt;
+    uint_x2_type a1 = static_cast<uint_x2_type>(is_neg(a1_) ? -a1_ : a1_);
+    uint_x2_type b1 = static_cast<uint_x2_type>(is_neg(b1_) ? -b1_ : b1_);
+    uint_x2_type a2 = static_cast<uint_x2_type>(is_neg(a2_) ? -a2_ : a2_);
+    uint_x2_type b2 = static_cast<uint_x2_type>(is_neg(b2_) ? -b2_ : b2_);
+
+    uint_x2_type l = a1 * b2;
+    uint_x2_type r = b1 * a2;
+
+    if (is_neg(a1_) ^ is_neg(b2_)) {
+      if (is_neg(a2_) ^ is_neg(b1_))
+        return (l > r) ? -to_fpt(l - r) : to_fpt(r - l);
+      else
+        return -to_fpt(l + r);
+    } else {
+      if (is_neg(a2_) ^ is_neg(b1_))
+        return to_fpt(l + r);
+      else
+        return (l < r) ? -to_fpt(r - l) : to_fpt(l - r);
+    }
+  }
+
+  typedef struct orientation_test {
+  public:
+    // Represents orientation test result.
+    enum Orientation {
+      RIGHT = -1,
+      COLLINEAR = 0,
+      LEFT = 1
+    };
+
+    // Value is a determinant of two vectors (e.g. x1 * y2 - x2 * y1).
+    // Return orientation based on the sign of the determinant.
+    template <typename T>
+    static Orientation eval(T value) {
+      if (is_zero(value)) return COLLINEAR;
+      return (is_neg(value)) ? RIGHT : LEFT;
+    }
+
+    static Orientation eval(int_x2_type dif_x1_,
+                            int_x2_type dif_y1_,
+                            int_x2_type dif_x2_,
+                            int_x2_type dif_y2_) {
+      return eval(robust_cross_product(dif_x1_, dif_y1_, dif_x2_, dif_y2_));
+    }
+
+    template <typename Point>
+    static Orientation eval(const Point &point1,
+                            const Point &point2,
+                            const Point &point3) {
+      int_x2_type dx1 = static_cast<int_x2_type>(point1.x()) -
+                        static_cast<int_x2_type>(point2.x());
+      int_x2_type dx2 = static_cast<int_x2_type>(point2.x()) -
+                        static_cast<int_x2_type>(point3.x());
+      int_x2_type dy1 = static_cast<int_x2_type>(point1.y()) -
+                        static_cast<int_x2_type>(point2.y());
+      int_x2_type dy2 = static_cast<int_x2_type>(point2.y()) -
+                        static_cast<int_x2_type>(point3.y());
+      return eval(robust_cross_product(dx1, dy1, dx2, dy2));
+    }
+  } ot;
+
+  template <typename Point>
+  class point_comparison_predicate {
+  public:
+    typedef Point point_type;
+
+    bool operator()(const point_type &lhs, const point_type &rhs) const {
+      if (lhs.x() == rhs.x())
+        return lhs.y() < rhs.y();
+      return lhs.x() < rhs.x();
+    }
+  };
+
+  template <typename Site, typename Circle>
+  class event_comparison_predicate {
+  public:
+    typedef Site site_type;
+    typedef Circle circle_type;
+
+    bool operator()(const site_type &lhs, const site_type &rhs) const {
+      if (lhs.x0() != rhs.x0())
+        return lhs.x0() < rhs.x0();
+      if (!lhs.is_segment()) {
+        if (!rhs.is_segment())
+          return lhs.y0() < rhs.y0();
+        if (is_vertical(rhs))
+          return lhs.y0() <= rhs.y0();
+        return true;
+      } else {
+        if (is_vertical(rhs)) {
+          if(is_vertical(lhs))
+            return lhs.y0() < rhs.y0();
+          return false;
+        }
+        if (is_vertical(lhs))
+          return true;
+        if (lhs.y0() != rhs.y0())
+          return lhs.y0() < rhs.y0();
+        return ot::eval(lhs.point1(), lhs.point0(), rhs.point1()) == ot::LEFT;
+      }
+    }
+
+    bool operator()(const site_type &lhs, const circle_type &rhs) const {
+      typename ulp_cmp_type::Result xCmp =
+          ulp_cmp(to_fpt(lhs.x()), to_fpt(rhs.lower_x()), ULPS);
+      if (xCmp != ulp_cmp_type::EQUAL)
+        return xCmp == ulp_cmp_type::LESS;
+      typename ulp_cmp_type::Result yCmp =
+          ulp_cmp(to_fpt(lhs.y()), to_fpt(rhs.lower_y()), ULPS);
+      return yCmp == ulp_cmp_type::LESS;
+    }
+
+    bool operator()(const circle_type &lhs, const site_type &rhs) const {
+      typename ulp_cmp_type::Result xCmp =
+          ulp_cmp(to_fpt(lhs.lower_x()), to_fpt(rhs.x()), ULPS);
+      if (xCmp != ulp_cmp_type::EQUAL)
+        return xCmp == ulp_cmp_type::LESS;
+      typename ulp_cmp_type::Result yCmp =
+          ulp_cmp(to_fpt(lhs.lower_y()), to_fpt(rhs.y()), ULPS);
+      return yCmp == ulp_cmp_type::LESS;
+    }
+
+    bool operator()(const circle_type &lhs, const circle_type &rhs) const {
+      typename ulp_cmp_type::Result xCmp =
+          ulp_cmp(to_fpt(lhs.lower_x()), to_fpt(rhs.lower_x()), ULPSx2);
+      if (xCmp != ulp_cmp_type::EQUAL)
+        return xCmp == ulp_cmp_type::LESS;
+      typename ulp_cmp_type::Result yCmp =
+          ulp_cmp(to_fpt(lhs.lower_y()), to_fpt(rhs.lower_y()), ULPSx2);
+      return yCmp == ulp_cmp_type::LESS;
+    }
+
+  private:
+    ulp_cmp_type ulp_cmp;
+    to_fpt_converter to_fpt;
+  };
+
+  template <typename Site>
+  class distance_predicate {
+  public:
+    typedef Site site_type;
+
+    // Returns true if a horizontal line going through a new site intersects
+    // right arc at first, else returns false. If horizontal line goes
+    // through intersection point of the given two arcs returns false also.
+    bool operator()(const site_type &left_site,
+                    const site_type &right_site,
+                    const site_type &new_site) const {
+      if (!left_site.is_segment()) {
+        if (!right_site.is_segment()) {
+          return pp(left_site, right_site, new_site);
+        } else {
+          return ps(left_site, right_site, new_site, false);
+        }
+      } else {
+        if (!right_site.is_segment()) {
+          return ps(right_site, left_site, new_site, true);
+        } else {
+          return ss(left_site, right_site, new_site);
+        }
+      }
+    }
+
+  private:
+    // Represents the result of the epsilon robust predicate. If the
+    // result is undefined some further processing is usually required.
+    enum kPredicateResult {
+      LESS = -1,
+      UNDEFINED = 0,
+      MORE = 1
+    };
+
+    typedef typename Site::point_type point_type;
+
+    // Robust predicate, avoids using high-precision libraries.
+    // Returns true if a horizontal line going through the new point site
+    // intersects right arc at first, else returns false. If horizontal line
+    // goes through intersection point of the given two arcs returns false.
+    bool pp(const site_type &left_site,
+            const site_type &right_site,
+            const site_type &new_site) const {
+      const point_type &left_point = left_site.point0();
+      const point_type &right_point = right_site.point0();
+      const point_type &new_point = new_site.point0();
+      if (left_point.x() > right_point.x()) {
+        if (new_point.y() <= left_point.y())
+          return false;
+      } else if (left_point.x() < right_point.x()) {
+        if (new_point.y() >= right_point.y())
+          return true;
+      } else {
+        return static_cast<int_x2_type>(left_point.y()) +
+               static_cast<int_x2_type>(right_point.y()) <
+               static_cast<int_x2_type>(new_point.y()) * 2;
+      }
+
+      fpt_type dist1 = find_distance_to_point_arc(left_site, new_point);
+      fpt_type dist2 = find_distance_to_point_arc(right_site, new_point);
+
+      // The undefined ulp range is equal to 3EPS + 3EPS <= 6ULP.
+      return dist1 < dist2;
+    }
+
+    bool ps(const site_type &left_site, const site_type &right_site,
+            const site_type &new_site, bool reverse_order) const {
+      kPredicateResult fast_res = fast_ps(
+        left_site, right_site, new_site, reverse_order);
+      if (fast_res != UNDEFINED)
+        return (fast_res == LESS);
+
+      fpt_type dist1 = find_distance_to_point_arc(
+          left_site, new_site.point0());
+      fpt_type dist2 = find_distance_to_segment_arc(
+          right_site, new_site.point0());
+
+      // The undefined ulp range is equal to 3EPS + 7EPS <= 10ULP.
+      return reverse_order ^ (dist1 < dist2);
+    }
+
+    bool ss(const site_type &left_site,
+            const site_type &right_site,
+            const site_type &new_site) const {
+      // Handle temporary segment sites.
+      if (left_site.point0() == right_site.point0() &&
+          left_site.point1() == right_site.point1()) {
+        return ot::eval(left_site.point0(),
+                        left_site.point1(),
+                        new_site.point0()) == ot::LEFT;
+      }
+
+      fpt_type dist1 = find_distance_to_segment_arc(
+          left_site, new_site.point0());
+      fpt_type dist2 = find_distance_to_segment_arc(
+          right_site, new_site.point0());
+
+      // The undefined ulp range is equal to 7EPS + 7EPS <= 14ULP.
+      return dist1 < dist2;
+    }
+
+    fpt_type find_distance_to_point_arc(
+        const site_type &site, const point_type &point) const {
+      fpt_type dx = to_fpt(site.x()) - to_fpt(point.x());
+      fpt_type dy = to_fpt(site.y()) - to_fpt(point.y());
+      // The relative error is at most 3EPS.
+      return (dx * dx + dy * dy) / (to_fpt(2.0) * dx);
+    }
+
+    fpt_type find_distance_to_segment_arc(
+        const site_type &site, const point_type &point) const {
+      if (is_vertical(site)) {
+        return (to_fpt(site.x()) - to_fpt(point.x())) * to_fpt(0.5);
+      } else {
+        const point_type &segment0 = site.point0(true);
+        const point_type &segment1 = site.point1(true);
+        fpt_type a1 = to_fpt(segment1.x()) - to_fpt(segment0.x());
+        fpt_type b1 = to_fpt(segment1.y()) - to_fpt(segment0.y());
+        fpt_type k = get_sqrt(a1 * a1 + b1 * b1);
+        // Avoid subtraction while computing k.
+        if (!is_neg(b1)) {
+          k = to_fpt(1.0) / (b1 + k);
+        } else {
+          k = (k - b1) / (a1 * a1);
+        }
+        // The relative error is at most 7EPS.
+        return k * robust_cross_product(
+            static_cast<int_x2_type>(segment1.x()) - static_cast<int_x2_type>(segment0.x()),
+            static_cast<int_x2_type>(segment1.y()) - static_cast<int_x2_type>(segment0.y()),
+            static_cast<int_x2_type>(point.x()) - static_cast<int_x2_type>(segment0.x()),
+            static_cast<int_x2_type>(point.y()) - static_cast<int_x2_type>(segment0.y()));
+      }
+    }
+
+    kPredicateResult fast_ps(
+        const site_type &left_site, const site_type &right_site,
+        const site_type &new_site, bool reverse_order) const {
+      const point_type &site_point = left_site.point0();
+      const point_type &segment_start = right_site.point0(true);
+      const point_type &segment_end = right_site.point1(true);
+      const point_type &new_point = new_site.point0();
+
+      if (ot::eval(segment_start, segment_end, new_point) != ot::RIGHT)
+        return (!right_site.is_inverse()) ? LESS : MORE;
+
+      fpt_type dif_x = to_fpt(new_point.x()) - to_fpt(site_point.x());
+      fpt_type dif_y = to_fpt(new_point.y()) - to_fpt(site_point.y());
+      fpt_type a = to_fpt(segment_end.x()) - to_fpt(segment_start.x());
+      fpt_type b = to_fpt(segment_end.y()) - to_fpt(segment_start.y());
+
+      if (is_vertical(right_site)) {
+        if (new_point.y() < site_point.y() && !reverse_order)
+          return MORE;
+        else if (new_point.y() > site_point.y() && reverse_order)
+          return LESS;
+        return UNDEFINED;
+      } else {
+        typename ot::Orientation orientation = ot::eval(
+            static_cast<int_x2_type>(segment_end.x()) - static_cast<int_x2_type>(segment_start.x()),
+            static_cast<int_x2_type>(segment_end.y()) - static_cast<int_x2_type>(segment_start.y()),
+            static_cast<int_x2_type>(new_point.x()) - static_cast<int_x2_type>(site_point.x()),
+            static_cast<int_x2_type>(new_point.y()) - static_cast<int_x2_type>(site_point.y()));
+        if (orientation == ot::LEFT) {
+          if (!right_site.is_inverse())
+            return reverse_order ? LESS : UNDEFINED;
+          return reverse_order ? UNDEFINED : MORE;
+        }
+      }
+
+      fpt_type fast_left_expr = a * (dif_y + dif_x) * (dif_y - dif_x);
+      fpt_type fast_right_expr = (to_fpt(2.0) * b) * dif_x * dif_y;
+      typename ulp_cmp_type::Result expr_cmp =
+          ulp_cmp(fast_left_expr, fast_right_expr, 4);
+      if (expr_cmp != ulp_cmp_type::EQUAL) {
+        if ((expr_cmp == ulp_cmp_type::MORE) ^ reverse_order)
+          return reverse_order ? LESS : MORE;
+        return UNDEFINED;
+      }
+      return UNDEFINED;
+    }
+
+  private:
+    ulp_cmp_type ulp_cmp;
+    to_fpt_converter to_fpt;
+  };
+
+  template <typename Node>
+  class node_comparison_predicate {
+  public:
+    typedef Node node_type;
+    typedef typename Node::site_type site_type;
+    typedef typename site_type::coordinate_type coordinate_type;
+    typedef distance_predicate<site_type> distance_predicate_type;
+
+    // Compares nodes in the balanced binary search tree. Nodes are
+    // compared based on the y coordinates of the arcs intersection points.
+    // Nodes with less y coordinate of the intersection point go first.
+    // Comparison is only called during the new site events processing.
+    // That's why one of the nodes will always lie on the sweepline and may
+    // be represented as a straight horizontal line.
+    bool operator() (const node_type &node1,
+                     const node_type &node2) const {
+      // Get x coordinate of the rightmost site from both nodes.
+      const site_type &site1 = get_comparison_site(node1);
+      const site_type &site2 = get_comparison_site(node2);
+
+      if (site1.x() < site2.x()) {
+        // The second node contains a new site.
+        return predicate_(node1.left_site(), node1.right_site(), site2);
+      } else if (site1.x() > site2.x()) {
+        // The first node contains a new site.
+        return !predicate_(node2.left_site(), node2.right_site(), site1);
+      } else {
+        // This checks were evaluated experimentally.
+        if (site1.index() == site2.index()) {
+          // Both nodes are new (inserted during same site event processing).
+          return get_comparison_y(node1) < get_comparison_y(node2);
+        } else if (site1.index() < site2.index()) {
+          std::pair<coordinate_type, int> y1 = get_comparison_y(node1, false);
+          std::pair<coordinate_type, int> y2 = get_comparison_y(node2, true);
+          if (y1.first != y2.first) return y1.first < y2.first;
+          return (!site1.is_segment()) ? (y1.second < 0) : false;
+        } else {
+          std::pair<coordinate_type, int> y1 = get_comparison_y(node1, true);
+          std::pair<coordinate_type, int> y2 = get_comparison_y(node2, false);
+          if (y1.first != y2.first) return y1.first < y2.first;
+          return (!site2.is_segment()) ? (y2.second > 0) : true;
+        }
+      }
+    }
+
+  private:
+    // Get the newer site.
+    const site_type &get_comparison_site(const node_type &node) const {
+      if (node.left_site().index() > node.right_site().index()) {
+        return node.left_site();
+      }
+      return node.right_site();
+    }
+
+    // Get comparison pair: y coordinate and direction of the newer site.
+    std::pair<coordinate_type, int> get_comparison_y(
+      const node_type &node, bool is_new_node = true) const {
+      if (node.left_site().index() == node.right_site().index()) {
+        return std::make_pair(node.left_site().y(), 0);
+      }
+      if (node.left_site().index() > node.right_site().index()) {
+        if (!is_new_node &&
+            node.left_site().is_segment() &&
+            is_vertical(node.left_site())) {
+          return std::make_pair(node.left_site().y1(), 1);
+        }
+        return std::make_pair(node.left_site().y(), 1);
+      }
+      return std::make_pair(node.right_site().y(), -1);
+    }
+
+    distance_predicate_type predicate_;
+  };
+
+  template <typename Site>
+  class circle_existence_predicate {
+  public:
+    typedef typename Site::point_type point_type;
+    typedef Site site_type;
+
+    bool ppp(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3) const {
+      return ot::eval(site1.point0(), site2.point0(), site3.point0()) ==
+             ot::RIGHT;
+    }
+
+    bool pps(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             int segment_index) const {
+      if (segment_index != 2) {
+        typename ot::Orientation orient1 = ot::eval(site1.point0(),
+            site2.point0(), site3.point0(true));
+        typename ot::Orientation orient2 = ot::eval(site1.point0(),
+            site2.point0(), site3.point1(true));
+        if (segment_index == 1 && site1.x0() >= site2.x0()) {
+          if (orient1 != ot::RIGHT)
+            return false;
+        } else if (segment_index == 3 && site2.x0() >= site1.x0()) {
+          if (orient2 != ot::RIGHT)
+            return false;
+        } else if (orient1 != ot::RIGHT && orient2 != ot::RIGHT) {
+          return false;
+        }
+      } else {
+        if (site3.point0(true) == site1.point0() &&
+            site3.point1(true) == site2.point0())
+          return false;
+      }
+      return true;
+    }
+
+    bool pss(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             int point_index) const {
+      if (site2.point0() == site3.point0() &&
+          site2.point1() == site3.point1()) {
+        return false;
+      }
+      if (point_index == 2) {
+        if (!site2.is_inverse() && site3.is_inverse())
+          return false;
+        if (site2.is_inverse() == site3.is_inverse() &&
+            ot::eval(site2.point0(true),
+                     site1.point0(),
+                     site3.point1(true)) != ot::RIGHT)
+          return false;
+      }
+      return true;
+    }
+
+    bool sss(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3) const {
+      if (site1.point0() == site2.point0() && site1.point1() == site2.point1())
+        return false;
+      if (site2.point0() == site3.point0() && site2.point1() == site3.point1())
+        return false;
+      return true;
+    }
+  };
+
+  template <typename Site, typename Circle>
+  class mp_circle_formation_functor {
+  public:
+    typedef typename Site::point_type point_type;
+    typedef Site site_type;
+    typedef Circle circle_type;
+    typedef robust_sqrt_expr<big_int_type, efpt_type, to_efpt_converter>
+        robust_sqrt_expr_type;
+
+    void ppp(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             circle_type &circle,
+             bool recompute_c_x = true,
+             bool recompute_c_y = true,
+             bool recompute_lower_x = true) {
+      big_int_type dif_x[3], dif_y[3], sum_x[2], sum_y[2];
+      dif_x[0] = static_cast<int_x2_type>(site1.x()) -
+                 static_cast<int_x2_type>(site2.x());
+      dif_x[1] = static_cast<int_x2_type>(site2.x()) -
+                 static_cast<int_x2_type>(site3.x());
+      dif_x[2] = static_cast<int_x2_type>(site1.x()) -
+                 static_cast<int_x2_type>(site3.x());
+      dif_y[0] = static_cast<int_x2_type>(site1.y()) -
+                 static_cast<int_x2_type>(site2.y());
+      dif_y[1] = static_cast<int_x2_type>(site2.y()) -
+                 static_cast<int_x2_type>(site3.y());
+      dif_y[2] = static_cast<int_x2_type>(site1.y()) -
+                 static_cast<int_x2_type>(site3.y());
+      sum_x[0] = static_cast<int_x2_type>(site1.x()) +
+                 static_cast<int_x2_type>(site2.x());
+      sum_x[1] = static_cast<int_x2_type>(site2.x()) +
+                 static_cast<int_x2_type>(site3.x());
+      sum_y[0] = static_cast<int_x2_type>(site1.y()) +
+                 static_cast<int_x2_type>(site2.y());
+      sum_y[1] = static_cast<int_x2_type>(site2.y()) +
+                 static_cast<int_x2_type>(site3.y());
+      fpt_type inv_denom = to_fpt(0.5) / to_fpt(static_cast<big_int_type>(
+          dif_x[0] * dif_y[1] - dif_x[1] * dif_y[0]));
+      big_int_type numer1 = dif_x[0] * sum_x[0] + dif_y[0] * sum_y[0];
+      big_int_type numer2 = dif_x[1] * sum_x[1] + dif_y[1] * sum_y[1];
+
+      if (recompute_c_x || recompute_lower_x) {
+        big_int_type c_x = numer1 * dif_y[1] - numer2 * dif_y[0];
+        circle.x(to_fpt(c_x) * inv_denom);
+
+        if (recompute_lower_x) {
+          // Evaluate radius of the circle.
+          big_int_type sqr_r = (dif_x[0] * dif_x[0] + dif_y[0] * dif_y[0]) *
+                               (dif_x[1] * dif_x[1] + dif_y[1] * dif_y[1]) *
+                               (dif_x[2] * dif_x[2] + dif_y[2] * dif_y[2]);
+          fpt_type r = get_sqrt(to_fpt(sqr_r));
+
+          // If c_x >= 0 then lower_x = c_x + r,
+          // else lower_x = (c_x * c_x - r * r) / (c_x - r).
+          // To guarantee epsilon relative error.
+          if (!is_neg(circle.x())) {
+            if (!is_neg(inv_denom)) {
+              circle.lower_x(circle.x() + r * inv_denom);
+            } else {
+              circle.lower_x(circle.x() - r * inv_denom);
+            }
+          } else {
+            big_int_type numer = c_x * c_x - sqr_r;
+            fpt_type lower_x = to_fpt(numer) * inv_denom / (to_fpt(c_x) + r);
+            circle.lower_x(lower_x);
+          }
+        }
+      }
+
+      if (recompute_c_y) {
+        big_int_type c_y = numer2 * dif_x[0] - numer1 * dif_x[1];
+        circle.y(to_fpt(c_y) * inv_denom);
+      }
+    }
+
+    // Recompute parameters of the circle event using high-precision library.
+    void pps(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             int segment_index,
+             circle_type &c_event,
+             bool recompute_c_x = true,
+             bool recompute_c_y = true,
+             bool recompute_lower_x = true) {
+      big_int_type cA[4], cB[4];
+      big_int_type line_a = static_cast<int_x2_type>(site3.point1(true).y()) -
+                            static_cast<int_x2_type>(site3.point0(true).y());
+      big_int_type line_b = static_cast<int_x2_type>(site3.point0(true).x()) -
+                            static_cast<int_x2_type>(site3.point1(true).x());
+      big_int_type segm_len = line_a * line_a + line_b * line_b;
+      big_int_type vec_x = static_cast<int_x2_type>(site2.y()) -
+                           static_cast<int_x2_type>(site1.y());
+      big_int_type vec_y = static_cast<int_x2_type>(site1.x()) -
+                           static_cast<int_x2_type>(site2.x());
+      big_int_type sum_x = static_cast<int_x2_type>(site1.x()) +
+                           static_cast<int_x2_type>(site2.x());
+      big_int_type sum_y = static_cast<int_x2_type>(site1.y()) +
+                           static_cast<int_x2_type>(site2.y());
+      big_int_type teta = line_a * vec_x + line_b * vec_y;
+      big_int_type denom = vec_x * line_b - vec_y * line_a;
+
+      big_int_type dif0 = static_cast<int_x2_type>(site3.point1().y()) -
+                          static_cast<int_x2_type>(site1.y());
+      big_int_type dif1 = static_cast<int_x2_type>(site1.x()) -
+                          static_cast<int_x2_type>(site3.point1().x());
+      big_int_type A = line_a * dif1 - line_b * dif0;
+      dif0 = static_cast<int_x2_type>(site3.point1().y()) -
+             static_cast<int_x2_type>(site2.y());
+      dif1 = static_cast<int_x2_type>(site2.x()) -
+             static_cast<int_x2_type>(site3.point1().x());
+      big_int_type B = line_a * dif1 - line_b * dif0;
+      big_int_type sum_AB = A + B;
+
+      if (is_zero(denom)) {
+        big_int_type numer = teta * teta - sum_AB * sum_AB;
+        big_int_type denom = teta * sum_AB;
+        cA[0] = denom * sum_x * 2 + numer * vec_x;
+        cB[0] = segm_len;
+        cA[1] = denom * sum_AB * 2 + numer * teta;
+        cB[1] = 1;
+        cA[2] = denom * sum_y * 2 + numer * vec_y;
+        fpt_type inv_denom = to_fpt(1.0) / to_fpt(denom);
+        if (recompute_c_x)
+          c_event.x(to_fpt(0.25) * to_fpt(cA[0]) * inv_denom);
+        if (recompute_c_y)
+          c_event.y(to_fpt(0.25) * to_fpt(cA[2]) * inv_denom);
+        if (recompute_lower_x) {
+          c_event.lower_x(to_fpt(0.25) * to_fpt(sqrt_expr_.eval2(cA, cB)) *
+              inv_denom / get_sqrt(to_fpt(segm_len)));
+        }
+        return;
+      }
+
+      big_int_type det = (teta * teta + denom * denom) * A * B * 4;
+      fpt_type inv_denom_sqr = to_fpt(1.0) / to_fpt(denom);
+      inv_denom_sqr *= inv_denom_sqr;
+
+      if (recompute_c_x || recompute_lower_x) {
+        cA[0] = sum_x * denom * denom + teta * sum_AB * vec_x;
+        cB[0] = 1;
+        cA[1] = (segment_index == 2) ? -vec_x : vec_x;
+        cB[1] = det;
+        if (recompute_c_x) {
+          c_event.x(to_fpt(0.5) * to_fpt(sqrt_expr_.eval2(cA, cB)) *
+              inv_denom_sqr);
+        }
+      }
+
+      if (recompute_c_y || recompute_lower_x) {
+        cA[2] = sum_y * denom * denom + teta * sum_AB * vec_y;
+        cB[2] = 1;
+        cA[3] = (segment_index == 2) ? -vec_y : vec_y;
+        cB[3] = det;
+        if (recompute_c_y) {
+          c_event.y(to_fpt(0.5) * to_fpt(sqrt_expr_.eval2(&cA[2], &cB[2])) *
+                    inv_denom_sqr);
+        }
+      }
+
+      if (recompute_lower_x) {
+        cB[0] = cB[0] * segm_len;
+        cB[1] = cB[1] * segm_len;
+        cA[2] = sum_AB * (denom * denom + teta * teta);
+        cB[2] = 1;
+        cA[3] = (segment_index == 2) ? -teta : teta;
+        cB[3] = det;
+        c_event.lower_x(to_fpt(0.5) * to_fpt(sqrt_expr_.eval4(cA, cB)) *
+            inv_denom_sqr / get_sqrt(to_fpt(segm_len)));
+      }
+    }
+
+    // Recompute parameters of the circle event using high-precision library.
+    void pss(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             int point_index,
+             circle_type &c_event,
+             bool recompute_c_x = true,
+             bool recompute_c_y = true,
+             bool recompute_lower_x = true) {
+      big_int_type a[2], b[2], c[2], cA[4], cB[4];
+      const point_type &segm_start1 = site2.point1(true);
+      const point_type &segm_end1 = site2.point0(true);
+      const point_type &segm_start2 = site3.point0(true);
+      const point_type &segm_end2 = site3.point1(true);
+      a[0] = static_cast<int_x2_type>(segm_end1.x()) -
+             static_cast<int_x2_type>(segm_start1.x());
+      b[0] = static_cast<int_x2_type>(segm_end1.y()) -
+             static_cast<int_x2_type>(segm_start1.y());
+      a[1] = static_cast<int_x2_type>(segm_end2.x()) -
+             static_cast<int_x2_type>(segm_start2.x());
+      b[1] = static_cast<int_x2_type>(segm_end2.y()) -
+             static_cast<int_x2_type>(segm_start2.y());
+      big_int_type orientation = a[1] * b[0] - a[0] * b[1];
+      if (is_zero(orientation)) {
+        fpt_type denom = to_fpt(2.0) * to_fpt(
+            static_cast<big_int_type>(a[0] * a[0] + b[0] * b[0]));
+        c[0] = b[0] * (static_cast<int_x2_type>(segm_start2.x()) -
+                       static_cast<int_x2_type>(segm_start1.x())) -
+               a[0] * (static_cast<int_x2_type>(segm_start2.y()) -
+                       static_cast<int_x2_type>(segm_start1.y()));
+        big_int_type dx = a[0] * (static_cast<int_x2_type>(site1.y()) -
+                                  static_cast<int_x2_type>(segm_start1.y())) -
+                          b[0] * (static_cast<int_x2_type>(site1.x()) -
+                                  static_cast<int_x2_type>(segm_start1.x()));
+        big_int_type dy = b[0] * (static_cast<int_x2_type>(site1.x()) -
+                                  static_cast<int_x2_type>(segm_start2.x())) -
+                          a[0] * (static_cast<int_x2_type>(site1.y()) -
+                                  static_cast<int_x2_type>(segm_start2.y()));
+        cB[0] = dx * dy;
+        cB[1] = 1;
+
+        if (recompute_c_y) {
+          cA[0] = b[0] * ((point_index == 2) ? 2 : -2);
+          cA[1] = a[0] * a[0] * (static_cast<int_x2_type>(segm_start1.y()) +
+                                 static_cast<int_x2_type>(segm_start2.y())) -
+                  a[0] * b[0] * (static_cast<int_x2_type>(segm_start1.x()) +
+                                 static_cast<int_x2_type>(segm_start2.x()) -
+                                 static_cast<int_x2_type>(site1.x()) * 2) +
+                  b[0] * b[0] * (static_cast<int_x2_type>(site1.y()) * 2);
+          fpt_type c_y = to_fpt(sqrt_expr_.eval2(cA, cB));
+          c_event.y(c_y / denom);
+        }
+
+        if (recompute_c_x || recompute_lower_x) {
+          cA[0] = a[0] * ((point_index == 2) ? 2 : -2);
+          cA[1] = b[0] * b[0] * (static_cast<int_x2_type>(segm_start1.x()) +
+                                 static_cast<int_x2_type>(segm_start2.x())) -
+                  a[0] * b[0] * (static_cast<int_x2_type>(segm_start1.y()) +
+                                 static_cast<int_x2_type>(segm_start2.y()) -
+                                 static_cast<int_x2_type>(site1.y()) * 2) +
+                  a[0] * a[0] * (static_cast<int_x2_type>(site1.x()) * 2);
+
+          if (recompute_c_x) {
+            fpt_type c_x = to_fpt(sqrt_expr_.eval2(cA, cB));
+            c_event.x(c_x / denom);
+          }
+
+          if (recompute_lower_x) {
+            cA[2] = is_neg(c[0]) ? -c[0] : c[0];
+            cB[2] = a[0] * a[0] + b[0] * b[0];
+            fpt_type lower_x = to_fpt(sqrt_expr_.eval3(cA, cB));
+            c_event.lower_x(lower_x / denom);
+          }
+        }
+        return;
+      }
+      c[0] = b[0] * segm_end1.x() - a[0] * segm_end1.y();
+      c[1] = a[1] * segm_end2.y() - b[1] * segm_end2.x();
+      big_int_type ix = a[0] * c[1] + a[1] * c[0];
+      big_int_type iy = b[0] * c[1] + b[1] * c[0];
+      big_int_type dx = ix - orientation * site1.x();
+      big_int_type dy = iy - orientation * site1.y();
+      if (is_zero(dx) && is_zero(dy)) {
+        fpt_type denom = to_fpt(orientation);
+        fpt_type c_x = to_fpt(ix) / denom;
+        fpt_type c_y = to_fpt(iy) / denom;
+        c_event = circle_type(c_x, c_y, c_x);
+        return;
+      }
+
+      big_int_type sign = ((point_index == 2) ? 1 : -1) *
+                          (is_neg(orientation) ? 1 : -1);
+      cA[0] = a[1] * -dx + b[1] * -dy;
+      cA[1] = a[0] * -dx + b[0] * -dy;
+      cA[2] = sign;
+      cA[3] = 0;
+      cB[0] = a[0] * a[0] + b[0] * b[0];
+      cB[1] = a[1] * a[1] + b[1] * b[1];
+      cB[2] = a[0] * a[1] + b[0] * b[1];
+      cB[3] = (a[0] * dy - b[0] * dx) * (a[1] * dy - b[1] * dx) * -2;
+      fpt_type temp = to_fpt(
+          sqrt_expr_evaluator_pss4<big_int_type, efpt_type>(cA, cB));
+      fpt_type denom = temp * to_fpt(orientation);
+
+      if (recompute_c_y) {
+        cA[0] = b[1] * (dx * dx + dy * dy) - iy * (dx * a[1] + dy * b[1]);
+        cA[1] = b[0] * (dx * dx + dy * dy) - iy * (dx * a[0] + dy * b[0]);
+        cA[2] = iy * sign;
+        fpt_type cy = to_fpt(
+            sqrt_expr_evaluator_pss4<big_int_type, efpt_type>(cA, cB));
+        c_event.y(cy / denom);
+      }
+
+      if (recompute_c_x || recompute_lower_x) {
+        cA[0] = a[1] * (dx * dx + dy * dy) - ix * (dx * a[1] + dy * b[1]);
+        cA[1] = a[0] * (dx * dx + dy * dy) - ix * (dx * a[0] + dy * b[0]);
+        cA[2] = ix * sign;
+
+        if (recompute_c_x) {
+          fpt_type cx = to_fpt(
+              sqrt_expr_evaluator_pss4<big_int_type, efpt_type>(cA, cB));
+          c_event.x(cx / denom);
+        }
+
+        if (recompute_lower_x) {
+          cA[3] = orientation * (dx * dx + dy * dy) * (is_neg(temp) ? -1 : 1);
+          fpt_type lower_x = to_fpt(
+              sqrt_expr_evaluator_pss4<big_int_type, efpt_type>(cA, cB));
+          c_event.lower_x(lower_x / denom);
+        }
+      }
+    }
+
+    // Recompute parameters of the circle event using high-precision library.
+    void sss(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             circle_type &c_event,
+             bool recompute_c_x = true,
+             bool recompute_c_y = true,
+             bool recompute_lower_x = true) {
+      big_int_type a[3], b[3], c[3], cA[4], cB[4];
+      // cA - corresponds to the cross product.
+      // cB - corresponds to the squared length.
+      a[0] = static_cast<int_x2_type>(site1.x1(true)) -
+             static_cast<int_x2_type>(site1.x0(true));
+      a[1] = static_cast<int_x2_type>(site2.x1(true)) -
+             static_cast<int_x2_type>(site2.x0(true));
+      a[2] = static_cast<int_x2_type>(site3.x1(true)) -
+             static_cast<int_x2_type>(site3.x0(true));
+
+      b[0] = static_cast<int_x2_type>(site1.y1(true)) -
+             static_cast<int_x2_type>(site1.y0(true));
+      b[1] = static_cast<int_x2_type>(site2.y1(true)) -
+             static_cast<int_x2_type>(site2.y0(true));
+      b[2] = static_cast<int_x2_type>(site3.y1(true)) -
+             static_cast<int_x2_type>(site3.y0(true));
+
+      c[0] = static_cast<int_x2_type>(site1.x0(true)) *
+             static_cast<int_x2_type>(site1.y1(true)) -
+             static_cast<int_x2_type>(site1.y0(true)) *
+             static_cast<int_x2_type>(site1.x1(true));
+      c[1] = static_cast<int_x2_type>(site2.x0(true)) *
+             static_cast<int_x2_type>(site2.y1(true)) -
+             static_cast<int_x2_type>(site2.y0(true)) *
+             static_cast<int_x2_type>(site2.x1(true));
+      c[2] = static_cast<int_x2_type>(site3.x0(true)) *
+             static_cast<int_x2_type>(site3.y1(true)) -
+             static_cast<int_x2_type>(site3.y0(true)) *
+             static_cast<int_x2_type>(site3.x1(true));
+
+      for (int i = 0; i < 3; ++i)
+        cB[i] = a[i] * a[i] + b[i] * b[i];
+
+      for (int i = 0; i < 3; ++i) {
+        int j = (i+1) % 3;
+        int k = (i+2) % 3;
+        cA[i] = a[j] * b[k] - a[k] * b[j];
+      }
+      fpt_type denom = to_fpt(sqrt_expr_.eval3(cA, cB));
+
+      if (recompute_c_y) {
+        for (int i = 0; i < 3; ++i) {
+          int j = (i+1) % 3;
+          int k = (i+2) % 3;
+          cA[i] = b[j] * c[k] - b[k] * c[j];
+        }
+        fpt_type c_y = to_fpt(sqrt_expr_.eval3(cA, cB));
+        c_event.y(c_y / denom);
+      }
+
+      if (recompute_c_x || recompute_lower_x) {
+        cA[3] = 0;
+        for (int i = 0; i < 3; ++i) {
+          int j = (i+1) % 3;
+          int k = (i+2) % 3;
+          cA[i] = a[j] * c[k] - a[k] * c[j];
+          if (recompute_lower_x) {
+            cA[3] = cA[3] + cA[i] * b[i];
+          }
+        }
+
+        if (recompute_c_x) {
+          fpt_type c_x = to_fpt(sqrt_expr_.eval3(cA, cB));
+          c_event.x(c_x / denom);
+        }
+
+        if (recompute_lower_x) {
+          cB[3] = 1;
+          fpt_type lower_x = to_fpt(sqrt_expr_.eval4(cA, cB));
+          c_event.lower_x(lower_x / denom);
+        }
+      }
+    }
+
+  private:
+    // Evaluates A[3] + A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]) +
+    //           A[2] * sqrt(B[3] * (sqrt(B[0] * B[1]) + B[2])).
+    template <typename _int, typename _fpt>
+    _fpt sqrt_expr_evaluator_pss4(_int *A, _int *B) {
+      _int cA[4], cB[4];
+      if (is_zero(A[3])) {
+        _fpt lh = sqrt_expr_.eval2(A, B);
+        cA[0] = 1;
+        cB[0] = B[0] * B[1];
+        cA[1] = B[2];
+        cB[1] = 1;
+        _fpt rh = sqrt_expr_.eval1(A+2, B+3) *
+            get_sqrt(sqrt_expr_.eval2(cA, cB));
+        if ((!is_neg(lh) && !is_neg(rh)) || (!is_pos(lh) && !is_pos(rh)))
+          return lh + rh;
+        cA[0] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] -
+                A[2] * A[2] * B[3] * B[2];
+        cB[0] = 1;
+        cA[1] = A[0] * A[1] * 2 - A[2] * A[2] * B[3];
+        cB[1] = B[0] * B[1];
+        _fpt numer = sqrt_expr_.eval2(cA, cB);
+        return numer / (lh - rh);
+      }
+      cA[0] = 1;
+      cB[0] = B[0] * B[1];
+      cA[1] = B[2];
+      cB[1] = 1;
+      _fpt rh = sqrt_expr_.eval1(A+2, B+3) * get_sqrt(sqrt_expr_.eval2(cA, cB));
+      cA[0] = A[0];
+      cB[0] = B[0];
+      cA[1] = A[1];
+      cB[1] = B[1];
+      cA[2] = A[3];
+      cB[2] = 1;
+      _fpt lh = sqrt_expr_.eval3(cA, cB);
+      if ((!is_neg(lh) && !is_neg(rh)) || (!is_pos(lh) && !is_pos(rh)))
+        return lh + rh;
+      cA[0] = A[3] * A[0] * 2;
+      cA[1] = A[3] * A[1] * 2;
+      cA[2] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] +
+              A[3] * A[3] - A[2] * A[2] * B[2] * B[3];
+      cA[3] = A[0] * A[1] * 2 - A[2] * A[2] * B[3];
+      cB[3] = B[0] * B[1];
+      _fpt numer = sqrt_expr_evaluator_pss3<_int, _fpt>(cA, cB);
+      return numer / (lh - rh);
+    }
+
+    template <typename _int, typename _fpt>
+    // Evaluates A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]) +
+    //           A[2] + A[3] * sqrt(B[0] * B[1]).
+    // B[3] = B[0] * B[1].
+    _fpt sqrt_expr_evaluator_pss3(_int *A, _int *B) {
+      _int cA[2], cB[2];
+      _fpt lh = sqrt_expr_.eval2(A, B);
+      _fpt rh = sqrt_expr_.eval2(A+2, B+2);
+      if ((!is_neg(lh) && !is_neg(rh)) || (!is_pos(lh) && !is_pos(rh)))
+        return lh + rh;
+      cA[0] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] -
+              A[2] * A[2] - A[3] * A[3] * B[0] * B[1];
+      cB[0] = 1;
+      cA[1] = (A[0] * A[1] - A[2] * A[3]) * 2;
+      cB[1] = B[3];
+      _fpt numer = sqrt_expr_.eval2(cA, cB);
+      return numer / (lh - rh);
+    }
+
+    robust_sqrt_expr_type sqrt_expr_;
+    to_fpt_converter to_fpt;
+  };
+
+  template <typename Site, typename Circle>
+  class lazy_circle_formation_functor {
+  public:
+    typedef robust_fpt<fpt_type> robust_fpt_type;
+    typedef robust_dif<robust_fpt_type> robust_dif_type;
+    typedef typename Site::point_type point_type;
+    typedef Site site_type;
+    typedef Circle circle_type;
+    typedef mp_circle_formation_functor<site_type, circle_type>
+        exact_circle_formation_functor_type;
+
+    void ppp(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             circle_type &c_event) {
+      fpt_type dif_x1 = to_fpt(site1.x()) - to_fpt(site2.x());
+      fpt_type dif_x2 = to_fpt(site2.x()) - to_fpt(site3.x());
+      fpt_type dif_y1 = to_fpt(site1.y()) - to_fpt(site2.y());
+      fpt_type dif_y2 = to_fpt(site2.y()) - to_fpt(site3.y());
+      fpt_type orientation = robust_cross_product(
+          static_cast<int_x2_type>(site1.x()) - static_cast<int_x2_type>(site2.x()),
+          static_cast<int_x2_type>(site2.x()) - static_cast<int_x2_type>(site3.x()),
+          static_cast<int_x2_type>(site1.y()) - static_cast<int_x2_type>(site2.y()),
+          static_cast<int_x2_type>(site2.y()) - static_cast<int_x2_type>(site3.y()));
+      robust_fpt_type inv_orientation(to_fpt(0.5) / orientation, to_fpt(2.0));
+      fpt_type sum_x1 = to_fpt(site1.x()) + to_fpt(site2.x());
+      fpt_type sum_x2 = to_fpt(site2.x()) + to_fpt(site3.x());
+      fpt_type sum_y1 = to_fpt(site1.y()) + to_fpt(site2.y());
+      fpt_type sum_y2 = to_fpt(site2.y()) + to_fpt(site3.y());
+      fpt_type dif_x3 = to_fpt(site1.x()) - to_fpt(site3.x());
+      fpt_type dif_y3 = to_fpt(site1.y()) - to_fpt(site3.y());
+      robust_dif_type c_x, c_y;
+      c_x += robust_fpt_type(dif_x1 * sum_x1 * dif_y2, to_fpt(2.0));
+      c_x += robust_fpt_type(dif_y1 * sum_y1 * dif_y2, to_fpt(2.0));
+      c_x -= robust_fpt_type(dif_x2 * sum_x2 * dif_y1, to_fpt(2.0));
+      c_x -= robust_fpt_type(dif_y2 * sum_y2 * dif_y1, to_fpt(2.0));
+      c_y += robust_fpt_type(dif_x2 * sum_x2 * dif_x1, to_fpt(2.0));
+      c_y += robust_fpt_type(dif_y2 * sum_y2 * dif_x1, to_fpt(2.0));
+      c_y -= robust_fpt_type(dif_x1 * sum_x1 * dif_x2, to_fpt(2.0));
+      c_y -= robust_fpt_type(dif_y1 * sum_y1 * dif_x2, to_fpt(2.0));
+      robust_dif_type lower_x(c_x);
+      lower_x -= robust_fpt_type(get_sqrt(
+          (dif_x1 * dif_x1 + dif_y1 * dif_y1) *
+          (dif_x2 * dif_x2 + dif_y2 * dif_y2) *
+          (dif_x3 * dif_x3 + dif_y3 * dif_y3)), to_fpt(5.0));
+      c_event = circle_type(
+          c_x.dif().fpv() * inv_orientation.fpv(),
+          c_y.dif().fpv() * inv_orientation.fpv(),
+          lower_x.dif().fpv() * inv_orientation.fpv());
+      bool recompute_c_x = c_x.dif().ulp() > ULPS;
+      bool recompute_c_y = c_y.dif().ulp() > ULPS;
+      bool recompute_lower_x = lower_x.dif().ulp() > ULPS;
+      if (recompute_c_x || recompute_c_y || recompute_lower_x) {
+        exact_circle_formation_functor_.ppp(
+            site1, site2, site3, c_event,
+            recompute_c_x, recompute_c_y, recompute_lower_x);
+      }
+    }
+
+    void pps(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             int segment_index,
+             circle_type &c_event) {
+      fpt_type line_a = to_fpt(site3.point1(true).y()) -
+                        to_fpt(site3.point0(true).y());
+      fpt_type line_b = to_fpt(site3.point0(true).x()) -
+                        to_fpt(site3.point1(true).x());
+      fpt_type vec_x = to_fpt(site2.y()) - to_fpt(site1.y());
+      fpt_type vec_y = to_fpt(site1.x()) - to_fpt(site2.x());
+      robust_fpt_type teta(robust_cross_product(
+          static_cast<int_x2_type>(site3.point1(true).y()) - static_cast<int_x2_type>(site3.point0(true).y()),
+          static_cast<int_x2_type>(site3.point0(true).x()) - static_cast<int_x2_type>(site3.point1(true).x()),
+          static_cast<int_x2_type>(site2.x()) - static_cast<int_x2_type>(site1.x()),
+          static_cast<int_x2_type>(site2.y()) - static_cast<int_x2_type>(site1.y())), to_fpt(1.0));
+      robust_fpt_type A(robust_cross_product(
+          static_cast<int_x2_type>(site3.point1(true).y()) - static_cast<int_x2_type>(site3.point0(true).y()),
+          static_cast<int_x2_type>(site3.point0(true).x()) - static_cast<int_x2_type>(site3.point1(true).x()),
+          static_cast<int_x2_type>(site3.point1().y()) - static_cast<int_x2_type>(site1.y()),
+          static_cast<int_x2_type>(site1.x()) - static_cast<int_x2_type>(site3.point1().x())), to_fpt(1.0));
+      robust_fpt_type B(robust_cross_product(
+          static_cast<int_x2_type>(site3.point1(true).y()) - static_cast<int_x2_type>(site3.point0(true).y()),
+          static_cast<int_x2_type>(site3.point0(true).x()) - static_cast<int_x2_type>(site3.point1(true).x()),
+          static_cast<int_x2_type>(site3.point1().y()) - static_cast<int_x2_type>(site2.y()),
+          static_cast<int_x2_type>(site2.x()) - static_cast<int_x2_type>(site3.point1().x())), to_fpt(1.0));
+      robust_fpt_type denom(robust_cross_product(
+          static_cast<int_x2_type>(site2.y()) - static_cast<int_x2_type>(site1.y()),
+          static_cast<int_x2_type>(site1.x()) - static_cast<int_x2_type>(site2.x()),
+          static_cast<int_x2_type>(site3.point1(true).y()) - static_cast<int_x2_type>(site3.point0(true).y()),
+          static_cast<int_x2_type>(site3.point0(true).x()) - static_cast<int_x2_type>(site3.point1(true).x())), to_fpt(1.0));
+      robust_fpt_type inv_segm_len(to_fpt(1.0) /
+          get_sqrt(line_a * line_a + line_b * line_b), to_fpt(3.0));
+      robust_dif_type t;
+      if (ot::eval(denom) == ot::COLLINEAR) {
+        t += teta / (robust_fpt_type(to_fpt(8.0)) * A);
+        t -= A / (robust_fpt_type(to_fpt(2.0)) * teta);
+      } else {
+        robust_fpt_type det = ((teta * teta + denom * denom) * A * B).sqrt();
+        if (segment_index == 2) {
+          t -= det / (denom * denom);
+        } else {
+          t += det / (denom * denom);
+        }
+        t += teta * (A + B) / (robust_fpt_type(to_fpt(2.0)) * denom * denom);
+      }
+      robust_dif_type c_x, c_y;
+      c_x += robust_fpt_type(to_fpt(0.5) * (to_fpt(site1.x()) +
+                                            to_fpt(site2.x())));
+      c_x += robust_fpt_type(vec_x) * t;
+      c_y += robust_fpt_type(to_fpt(0.5) * (to_fpt(site1.y()) +
+                                            to_fpt(site2.y())));
+      c_y += robust_fpt_type(vec_y) * t;
+      robust_dif_type r, lower_x(c_x);
+      r -= robust_fpt_type(line_a) * robust_fpt_type(site3.x0());
+      r -= robust_fpt_type(line_b) * robust_fpt_type(site3.y0());
+      r += robust_fpt_type(line_a) * c_x;
+      r += robust_fpt_type(line_b) * c_y;
+      if (r.pos().fpv() < r.neg().fpv())
+        r = -r;
+      lower_x += r * inv_segm_len;
+      c_event = circle_type(
+          c_x.dif().fpv(), c_y.dif().fpv(), lower_x.dif().fpv());
+      bool recompute_c_x = c_x.dif().ulp() > ULPS;
+      bool recompute_c_y = c_y.dif().ulp() > ULPS;
+      bool recompute_lower_x = lower_x.dif().ulp() > ULPS;
+      if (recompute_c_x || recompute_c_y || recompute_lower_x) {
+        exact_circle_formation_functor_.pps(
+            site1, site2, site3, segment_index, c_event,
+            recompute_c_x, recompute_c_y, recompute_lower_x);
+      }
+    }
+
+    void pss(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             int point_index,
+             circle_type &c_event) {
+      const point_type &segm_start1 = site2.point1(true);
+      const point_type &segm_end1 = site2.point0(true);
+      const point_type &segm_start2 = site3.point0(true);
+      const point_type &segm_end2 = site3.point1(true);
+      fpt_type a1 = to_fpt(segm_end1.x()) - to_fpt(segm_start1.x());
+      fpt_type b1 = to_fpt(segm_end1.y()) - to_fpt(segm_start1.y());
+      fpt_type a2 = to_fpt(segm_end2.x()) - to_fpt(segm_start2.x());
+      fpt_type b2 = to_fpt(segm_end2.y()) - to_fpt(segm_start2.y());
+      bool recompute_c_x, recompute_c_y, recompute_lower_x;
+      robust_fpt_type orientation(robust_cross_product(
+        static_cast<int_x2_type>(segm_end1.y()) - static_cast<int_x2_type>(segm_start1.y()),
+        static_cast<int_x2_type>(segm_end1.x()) - static_cast<int_x2_type>(segm_start1.x()),
+        static_cast<int_x2_type>(segm_end2.y()) - static_cast<int_x2_type>(segm_start2.y()),
+        static_cast<int_x2_type>(segm_end2.x()) - static_cast<int_x2_type>(segm_start2.x())), to_fpt(1.0));
+      if (ot::eval(orientation) == ot::COLLINEAR) {
+        robust_fpt_type a(a1 * a1 + b1 * b1, to_fpt(2.0));
+        robust_fpt_type c(robust_cross_product(
+            static_cast<int_x2_type>(segm_end1.y()) - static_cast<int_x2_type>(segm_start1.y()),
+            static_cast<int_x2_type>(segm_end1.x()) - static_cast<int_x2_type>(segm_start1.x()),
+            static_cast<int_x2_type>(segm_start2.y()) - static_cast<int_x2_type>(segm_start1.y()),
+            static_cast<int_x2_type>(segm_start2.x()) - static_cast<int_x2_type>(segm_start1.x())), to_fpt(1.0));
+        robust_fpt_type det(
+            robust_cross_product(
+                static_cast<int_x2_type>(segm_end1.x()) - static_cast<int_x2_type>(segm_start1.x()),
+                static_cast<int_x2_type>(segm_end1.y()) - static_cast<int_x2_type>(segm_start1.y()),
+                static_cast<int_x2_type>(site1.x()) - static_cast<int_x2_type>(segm_start1.x()),
+                static_cast<int_x2_type>(site1.y()) - static_cast<int_x2_type>(segm_start1.y())) *
+            robust_cross_product(
+                static_cast<int_x2_type>(segm_end1.y()) - static_cast<int_x2_type>(segm_start1.y()),
+                static_cast<int_x2_type>(segm_end1.x()) - static_cast<int_x2_type>(segm_start1.x()),
+                static_cast<int_x2_type>(site1.y()) - static_cast<int_x2_type>(segm_start2.y()),
+                static_cast<int_x2_type>(site1.x()) - static_cast<int_x2_type>(segm_start2.x())),
+            to_fpt(3.0));
+        robust_dif_type t;
+        t -= robust_fpt_type(a1) * robust_fpt_type((
+             to_fpt(segm_start1.x()) + to_fpt(segm_start2.x())) * to_fpt(0.5) -
+             to_fpt(site1.x()));
+        t -= robust_fpt_type(b1) * robust_fpt_type((
+             to_fpt(segm_start1.y()) + to_fpt(segm_start2.y())) * to_fpt(0.5) -
+             to_fpt(site1.y()));
+        if (point_index == 2) {
+          t += det.sqrt();
+        } else {
+          t -= det.sqrt();
+        }
+        t /= a;
+        robust_dif_type c_x, c_y;
+        c_x += robust_fpt_type(to_fpt(0.5) * (
+            to_fpt(segm_start1.x()) + to_fpt(segm_start2.x())));
+        c_x += robust_fpt_type(a1) * t;
+        c_y += robust_fpt_type(to_fpt(0.5) * (
+            to_fpt(segm_start1.y()) + to_fpt(segm_start2.y())));
+        c_y += robust_fpt_type(b1) * t;
+        robust_dif_type lower_x(c_x);
+        if (is_neg(c)) {
+          lower_x -= robust_fpt_type(to_fpt(0.5)) * c / a.sqrt();
+        } else {
+          lower_x += robust_fpt_type(to_fpt(0.5)) * c / a.sqrt();
+        }
+        recompute_c_x = c_x.dif().ulp() > ULPS;
+        recompute_c_y = c_y.dif().ulp() > ULPS;
+        recompute_lower_x = lower_x.dif().ulp() > ULPS;
+        c_event =
+            circle_type(c_x.dif().fpv(), c_y.dif().fpv(), lower_x.dif().fpv());
+      } else {
+        robust_fpt_type sqr_sum1(get_sqrt(a1 * a1 + b1 * b1), to_fpt(2.0));
+        robust_fpt_type sqr_sum2(get_sqrt(a2 * a2 + b2 * b2), to_fpt(2.0));
+        robust_fpt_type a(robust_cross_product(
+          static_cast<int_x2_type>(segm_end1.x()) - static_cast<int_x2_type>(segm_start1.x()),
+          static_cast<int_x2_type>(segm_end1.y()) - static_cast<int_x2_type>(segm_start1.y()),
+          static_cast<int_x2_type>(segm_start2.y()) - static_cast<int_x2_type>(segm_end2.y()),
+          static_cast<int_x2_type>(segm_end2.x()) - static_cast<int_x2_type>(segm_start2.x())), to_fpt(1.0));
+        if (!is_neg(a)) {
+          a += sqr_sum1 * sqr_sum2;
+        } else {
+          a = (orientation * orientation) / (sqr_sum1 * sqr_sum2 - a);
+        }
+        robust_fpt_type or1(robust_cross_product(
+            static_cast<int_x2_type>(segm_end1.y()) - static_cast<int_x2_type>(segm_start1.y()),
+            static_cast<int_x2_type>(segm_end1.x()) - static_cast<int_x2_type>(segm_start1.x()),
+            static_cast<int_x2_type>(segm_end1.y()) - static_cast<int_x2_type>(site1.y()),
+            static_cast<int_x2_type>(segm_end1.x()) - static_cast<int_x2_type>(site1.x())), to_fpt(1.0));
+        robust_fpt_type or2(robust_cross_product(
+            static_cast<int_x2_type>(segm_end2.x()) - static_cast<int_x2_type>(segm_start2.x()),
+            static_cast<int_x2_type>(segm_end2.y()) - static_cast<int_x2_type>(segm_start2.y()),
+            static_cast<int_x2_type>(segm_end2.x()) - static_cast<int_x2_type>(site1.x()),
+            static_cast<int_x2_type>(segm_end2.y()) - static_cast<int_x2_type>(site1.y())), to_fpt(1.0));
+        robust_fpt_type det = robust_fpt_type(to_fpt(2.0)) * a * or1 * or2;
+        robust_fpt_type c1(robust_cross_product(
+            static_cast<int_x2_type>(segm_end1.y()) - static_cast<int_x2_type>(segm_start1.y()),
+            static_cast<int_x2_type>(segm_end1.x()) - static_cast<int_x2_type>(segm_start1.x()),
+            static_cast<int_x2_type>(segm_end1.y()),
+            static_cast<int_x2_type>(segm_end1.x())), to_fpt(1.0));
+        robust_fpt_type c2(robust_cross_product(
+            static_cast<int_x2_type>(segm_end2.x()) - static_cast<int_x2_type>(segm_start2.x()),
+            static_cast<int_x2_type>(segm_end2.y()) - static_cast<int_x2_type>(segm_start2.y()),
+            static_cast<int_x2_type>(segm_end2.x()),
+            static_cast<int_x2_type>(segm_end2.y())), to_fpt(1.0));
+        robust_fpt_type inv_orientation = robust_fpt_type(to_fpt(1.0)) / orientation;
+        robust_dif_type t, b, ix, iy;
+        ix += robust_fpt_type(a2) * c1 * inv_orientation;
+        ix += robust_fpt_type(a1) * c2 * inv_orientation;
+        iy += robust_fpt_type(b1) * c2 * inv_orientation;
+        iy += robust_fpt_type(b2) * c1 * inv_orientation;
+
+        b += ix * (robust_fpt_type(a1) * sqr_sum2);
+        b += ix * (robust_fpt_type(a2) * sqr_sum1);
+        b += iy * (robust_fpt_type(b1) * sqr_sum2);
+        b += iy * (robust_fpt_type(b2) * sqr_sum1);
+        b -= sqr_sum1 * robust_fpt_type(robust_cross_product(
+            static_cast<int_x2_type>(segm_end2.x()) - static_cast<int_x2_type>(segm_start2.x()),
+            static_cast<int_x2_type>(segm_end2.y()) - static_cast<int_x2_type>(segm_start2.y()),
+            static_cast<int_x2_type>(-site1.y()),
+            static_cast<int_x2_type>(site1.x())), to_fpt(1.0));
+        b -= sqr_sum2 * robust_fpt_type(robust_cross_product(
+            static_cast<int_x2_type>(segm_end1.x()) - static_cast<int_x2_type>(segm_start1.x()),
+            static_cast<int_x2_type>(segm_end1.y()) - static_cast<int_x2_type>(segm_start1.y()),
+            static_cast<int_x2_type>(-site1.y()),
+            static_cast<int_x2_type>(site1.x())), to_fpt(1.0));
+        t -= b;
+        if (point_index == 2) {
+          t += det.sqrt();
+        } else {
+          t -= det.sqrt();
+        }
+        t /= (a * a);
+        robust_dif_type c_x(ix), c_y(iy);
+        c_x += t * (robust_fpt_type(a1) * sqr_sum2);
+        c_x += t * (robust_fpt_type(a2) * sqr_sum1);
+        c_y += t * (robust_fpt_type(b1) * sqr_sum2);
+        c_y += t * (robust_fpt_type(b2) * sqr_sum1);
+        if (t.pos().fpv() < t.neg().fpv()) {
+          t = -t;
+        }
+        robust_dif_type lower_x(c_x);
+        if (is_neg(orientation)) {
+          lower_x -= t * orientation;
+        } else {
+          lower_x += t * orientation;
+        }
+        recompute_c_x = c_x.dif().ulp() > ULPS;
+        recompute_c_y = c_y.dif().ulp() > ULPS;
+        recompute_lower_x = lower_x.dif().ulp() > ULPS;
+        c_event = circle_type(
+            c_x.dif().fpv(), c_y.dif().fpv(), lower_x.dif().fpv());
+      }
+      if (recompute_c_x || recompute_c_y || recompute_lower_x) {
+          exact_circle_formation_functor_.pss(
+              site1, site2, site3, point_index, c_event,
+        recompute_c_x, recompute_c_y, recompute_lower_x);
+      }
+    }
+
+    void sss(const site_type &site1,
+             const site_type &site2,
+             const site_type &site3,
+             circle_type &c_event) {
+      robust_fpt_type a1(to_fpt(site1.x1(true)) - to_fpt(site1.x0(true)));
+      robust_fpt_type b1(to_fpt(site1.y1(true)) - to_fpt(site1.y0(true)));
+      robust_fpt_type c1(robust_cross_product(
+          site1.x0(true), site1.y0(true),
+          site1.x1(true), site1.y1(true)), to_fpt(1.0));
+
+      robust_fpt_type a2(to_fpt(site2.x1(true)) - to_fpt(site2.x0(true)));
+      robust_fpt_type b2(to_fpt(site2.y1(true)) - to_fpt(site2.y0(true)));
+      robust_fpt_type c2(robust_cross_product(
+          site2.x0(true), site2.y0(true),
+          site2.x1(true), site2.y1(true)), to_fpt(1.0));
+
+      robust_fpt_type a3(to_fpt(site3.x1(true)) - to_fpt(site3.x0(true)));
+      robust_fpt_type b3(to_fpt(site3.y1(true)) - to_fpt(site3.y0(true)));
+      robust_fpt_type c3(robust_cross_product(
+          site3.x0(true), site3.y0(true),
+          site3.x1(true), site3.y1(true)), to_fpt(1.0));
+
+      robust_fpt_type len1 = (a1 * a1 + b1 * b1).sqrt();
+      robust_fpt_type len2 = (a2 * a2 + b2 * b2).sqrt();
+      robust_fpt_type len3 = (a3 * a3 + b3 * b3).sqrt();
+      robust_fpt_type cross_12(robust_cross_product(
+          static_cast<int_x2_type>(site1.x1(true)) - static_cast<int_x2_type>(site1.x0(true)),
+          static_cast<int_x2_type>(site1.y1(true)) - static_cast<int_x2_type>(site1.y0(true)),
+          static_cast<int_x2_type>(site2.x1(true)) - static_cast<int_x2_type>(site2.x0(true)),
+          static_cast<int_x2_type>(site2.y1(true)) - static_cast<int_x2_type>(site2.y0(true))), to_fpt(1.0));
+      robust_fpt_type cross_23(robust_cross_product(
+          static_cast<int_x2_type>(site2.x1(true)) - static_cast<int_x2_type>(site2.x0(true)),
+          static_cast<int_x2_type>(site2.y1(true)) - static_cast<int_x2_type>(site2.y0(true)),
+          static_cast<int_x2_type>(site3.x1(true)) - static_cast<int_x2_type>(site3.x0(true)),
+          static_cast<int_x2_type>(site3.y1(true)) - static_cast<int_x2_type>(site3.y0(true))), to_fpt(1.0));
+      robust_fpt_type cross_31(robust_cross_product(
+          static_cast<int_x2_type>(site3.x1(true)) - static_cast<int_x2_type>(site3.x0(true)),
+          static_cast<int_x2_type>(site3.y1(true)) - static_cast<int_x2_type>(site3.y0(true)),
+          static_cast<int_x2_type>(site1.x1(true)) - static_cast<int_x2_type>(site1.x0(true)),
+          static_cast<int_x2_type>(site1.y1(true)) - static_cast<int_x2_type>(site1.y0(true))), to_fpt(1.0));
+      robust_dif_type denom, c_x, c_y, r;
+
+      // denom = cross_12 * len3 + cross_23 * len1 + cross_31 * len2.
+      denom += cross_12 * len3;
+      denom += cross_23 * len1;
+      denom += cross_31 * len2;
+
+      // denom * r = (b2 * c_x - a2 * c_y - c2 * denom) / len2.
+      r -= cross_12 * c3;
+      r -= cross_23 * c1;
+      r -= cross_31 * c2;
+
+      c_x += a1 * c2 * len3;
+      c_x -= a2 * c1 * len3;
+      c_x += a2 * c3 * len1;
+      c_x -= a3 * c2 * len1;
+      c_x += a3 * c1 * len2;
+      c_x -= a1 * c3 * len2;
+      c_y += b1 * c2 * len3;
+      c_y -= b2 * c1 * len3;
+      c_y += b2 * c3 * len1;
+      c_y -= b3 * c2 * len1;
+      c_y += b3 * c1 * len2;
+      c_y -= b1 * c3 * len2;
+      robust_dif_type lower_x(c_x + r);
+      bool recompute_c_x = c_x.dif().ulp() > ULPS;
+      bool recompute_c_y = c_y.dif().ulp() > ULPS;
+      bool recompute_lower_x = lower_x.dif().ulp() > ULPS;
+      bool recompute_denom = denom.dif().ulp() > ULPS;
+      c_event = circle_type(
+          c_x.dif().fpv() / denom.dif().fpv(),
+          c_y.dif().fpv() / denom.dif().fpv(),
+          lower_x.dif().fpv() / denom.dif().fpv());
+      if (recompute_c_x || recompute_c_y ||
+          recompute_lower_x || recompute_denom) {
+        exact_circle_formation_functor_.sss(
+            site1, site2, site3, c_event,
+            recompute_c_x, recompute_c_y, recompute_lower_x);
+      }
+    }
+
+  private:
+    exact_circle_formation_functor_type exact_circle_formation_functor_;
+    to_fpt_converter to_fpt;
+  };
+
+  template <typename Site,
+            typename Circle,
+            typename CEP = circle_existence_predicate<Site>,
+            typename CFF = lazy_circle_formation_functor<Site, Circle> >
+  class circle_formation_predicate {
+  public:
+    typedef Site site_type;
+    typedef Circle circle_type;
+    typedef CEP circle_existence_predicate_type;
+    typedef CFF circle_formation_functor_type;
+
+    // Create a circle event from the given three sites.
+    // Returns true if the circle event exists, else false.
+    // If exists circle event is saved into the c_event variable.
+    bool operator()(const site_type &site1, const site_type &site2,
+                    const site_type &site3, circle_type &circle) {
+      if (!site1.is_segment()) {
+        if (!site2.is_segment()) {
+          if (!site3.is_segment()) {
+            // (point, point, point) sites.
+            if (!circle_existence_predicate_.ppp(site1, site2, site3))
+              return false;
+            circle_formation_functor_.ppp(site1, site2, site3, circle);
+          } else {
+            // (point, point, segment) sites.
+            if (!circle_existence_predicate_.pps(site1, site2, site3, 3))
+              return false;
+            circle_formation_functor_.pps(site1, site2, site3, 3, circle);
+          }
+        } else {
+          if (!site3.is_segment()) {
+            // (point, segment, point) sites.
+            if (!circle_existence_predicate_.pps(site1, site3, site2, 2))
+              return false;
+            circle_formation_functor_.pps(site1, site3, site2, 2, circle);
+          } else {
+            // (point, segment, segment) sites.
+            if (!circle_existence_predicate_.pss(site1, site2, site3, 1))
+              return false;
+            circle_formation_functor_.pss(site1, site2, site3, 1, circle);
+          }
+        }
+      } else {
+        if (!site2.is_segment()) {
+          if (!site3.is_segment()) {
+            // (segment, point, point) sites.
+            if (!circle_existence_predicate_.pps(site2, site3, site1, 1))
+              return false;
+            circle_formation_functor_.pps(site2, site3, site1, 1, circle);
+          } else {
+            // (segment, point, segment) sites.
+            if (!circle_existence_predicate_.pss(site2, site1, site3, 2))
+              return false;
+            circle_formation_functor_.pss(site2, site1, site3, 2, circle);
+          }
+        } else {
+          if (!site3.is_segment()) {
+            // (segment, segment, point) sites.
+            if (!circle_existence_predicate_.pss(site3, site1, site2, 3))
+              return false;
+            circle_formation_functor_.pss(site3, site1, site2, 3, circle);
+          } else {
+            // (segment, segment, segment) sites.
+            if (!circle_existence_predicate_.sss(site1, site2, site3))
+              return false;
+            circle_formation_functor_.sss(site1, site2, site3, circle);
+          }
+        }
+      }
+      return true;
+    }
+
+  private:
+    circle_existence_predicate_type circle_existence_predicate_;
+    circle_formation_functor_type circle_formation_functor_;
+  };
+};
+}  // detail
+}  // polygon
+}  // boost
+
+#endif  // BOOST_POLYGON_DETAIL_VORONOI_PREDICATES
Added: trunk/boost/polygon/detail/voronoi_robust_fpt.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/detail/voronoi_robust_fpt.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,515 @@
+// Boost.Polygon library detail/voronoi_robust_fpt.hpp header file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POLYGON_DETAIL_VORONOI_ROBUST_FPT
+#define BOOST_POLYGON_DETAIL_VORONOI_ROBUST_FPT
+
+#include <cmath>
+
+// Geometry predicates with floating-point variables usually require
+// high-precision predicates to retrieve the correct result.
+// Epsilon robust predicates give the result within some epsilon relative
+// error, but are a lot faster than high-precision predicates.
+// To make algorithm robust and efficient epsilon robust predicates are
+// used at the first step. In case of the undefined result high-precision
+// arithmetic is used to produce required robustness. This approach
+// requires exact computation of epsilon intervals within which epsilon
+// robust predicates have undefined value.
+// There are two ways to measure an error of floating-point calculations:
+// relative error and ULPs (units in the last place).
+// Let EPS be machine epsilon, then next inequalities have place:
+// 1 EPS <= 1 ULP <= 2 EPS (1), 0.5 ULP <= 1 EPS <= 1 ULP (2).
+// ULPs are good for measuring rounding errors and comparing values.
+// Relative errors are good for computation of general relative
+// error of formulas or expressions. So to calculate epsilon
+// interval within which epsilon robust predicates have undefined result
+// next schema is used:
+//     1) Compute rounding errors of initial variables using ULPs;
+//     2) Transform ULPs to epsilons using upper bound of the (1);
+//     3) Compute relative error of the formula using epsilon arithmetic;
+//     4) Transform epsilon to ULPs using upper bound of the (2);
+// In case two values are inside undefined ULP range use high-precision
+// arithmetic to produce the correct result, else output the result.
+// Look at almost_equal function to see how two floating-point variables
+// are checked to fit in the ULP range.
+// If A has relative error of r(A) and B has relative error of r(B) then:
+//     1) r(A + B) <= max(r(A), r(B)), for A * B >= 0;
+//     2) r(A - B) <= B*r(A)+A*r(B)/(A-B), for A * B >= 0;
+//     2) r(A * B) <= r(A) + r(B);
+//     3) r(A / B) <= r(A) + r(B);
+// In addition rounding error should be added, that is always equal to
+// 0.5 ULP or at most 1 epsilon. As you might see from the above formulas
+// subtraction relative error may be extremely large, that's why
+// epsilon robust comparator class is used to store floating point values
+// and compute subtraction as the final step of the evaluation.
+// For further information about relative errors and ULPs try this link:
+// http://docs.sun.com/source/806-3568/ncg_goldberg.html
+
+namespace boost {
+namespace polygon {
+namespace detail {
+
+template <typename T>
+T get_sqrt(const T& that) {
+  return (std::sqrt)(that);
+}
+
+template <typename T>
+bool is_pos(const T& that) {
+  return that > 0;
+}
+
+template <typename T>
+bool is_neg(const T& that) {
+  return that < 0;
+}
+
+template <typename T>
+bool is_zero(const T& that) {
+  return that == 0;
+}
+
+template <typename _fpt>
+class robust_fpt {
+public:
+  typedef _fpt floating_point_type;
+  typedef _fpt relative_error_type;
+
+  // Rounding error is at most 1 EPS.
+  static const relative_error_type ROUNDING_ERROR;
+
+  robust_fpt() : fpv_(0.0), re_(0.0) {}
+  robust_fpt(floating_point_type fpv) :
+      fpv_(fpv), re_(0.0) {}
+  robust_fpt(floating_point_type fpv, relative_error_type error) :
+      fpv_(fpv), re_(error) {}
+
+  floating_point_type fpv() const { return fpv_; }
+  relative_error_type re() const { return re_; }
+  relative_error_type ulp() const { return re_; }
+
+  robust_fpt& operator=(const robust_fpt &that) {
+    this->fpv_ = that.fpv_;
+    this->re_ = that.re_;
+    return *this;
+  }
+
+  bool has_pos_value() const {
+    return is_pos(fpv_);
+  }
+
+  bool has_neg_value() const {
+    return is_neg(fpv_);
+  }
+
+  bool has_zero_value() const {
+    return is_zero(fpv_);
+  }
+
+  robust_fpt operator-() const {
+    return robust_fpt(-fpv_, re_);
+  }
+
+  robust_fpt& operator+=(const robust_fpt &that) {
+    floating_point_type fpv = this->fpv_ + that.fpv_;
+    if ((!is_neg(this->fpv_) && !is_neg(that.fpv_)) ||
+        (!is_pos(this->fpv_) && !is_pos(that.fpv_)))
+      this->re_ = (std::max)(this->re_, that.re_) + ROUNDING_ERROR;
+    else {
+      floating_point_type temp =
+        (this->fpv_ * this->re_ - that.fpv_ * that.re_) / fpv;
+      if (is_neg(temp))
+        temp = -temp;
+      this->re_ = temp + ROUNDING_ERROR;
+    }
+    this->fpv_ = fpv;
+    return *this;
+  }
+
+  robust_fpt& operator-=(const robust_fpt &that) {
+    floating_point_type fpv = this->fpv_ - that.fpv_;
+    if ((!is_neg(this->fpv_) && !is_pos(that.fpv_)) ||
+        (!is_pos(this->fpv_) && !is_neg(that.fpv_)))
+       this->re_ = (std::max)(this->re_, that.re_) + ROUNDING_ERROR;
+    else {
+      floating_point_type temp =
+        (this->fpv_ * this->re_ + that.fpv_ * that.re_) / fpv;
+      if (is_neg(temp))
+         temp = -temp;
+      this->re_ = temp + ROUNDING_ERROR;
+    }
+    this->fpv_ = fpv;
+    return *this;
+  }
+
+  robust_fpt& operator*=(const robust_fpt &that) {
+    this->re_ += that.re_ + ROUNDING_ERROR;
+    this->fpv_ *= that.fpv_;
+    return *this;
+  }
+
+  robust_fpt& operator/=(const robust_fpt &that) {
+    this->re_ += that.re_ + ROUNDING_ERROR;
+    this->fpv_ /= that.fpv_;
+    return *this;
+  }
+
+  robust_fpt operator+(const robust_fpt &that) const {
+    floating_point_type fpv = this->fpv_ + that.fpv_;
+    relative_error_type re;
+    if ((!is_neg(this->fpv_) && !is_neg(that.fpv_)) ||
+        (!is_pos(this->fpv_) && !is_pos(that.fpv_)))
+      re = (std::max)(this->re_, that.re_) + ROUNDING_ERROR;
+    else {
+      floating_point_type temp =
+        (this->fpv_ * this->re_ - that.fpv_ * that.re_) / fpv;
+      if (is_neg(temp))
+        temp = -temp;
+      re = temp + ROUNDING_ERROR;
+    }
+    return robust_fpt(fpv, re);
+  }
+
+  robust_fpt operator-(const robust_fpt &that) const {
+    floating_point_type fpv = this->fpv_ - that.fpv_;
+    relative_error_type re;
+    if ((!is_neg(this->fpv_) && !is_pos(that.fpv_)) ||
+        (!is_pos(this->fpv_) && !is_neg(that.fpv_)))
+      re = (std::max)(this->re_, that.re_) + ROUNDING_ERROR;
+    else {
+      floating_point_type temp =
+        (this->fpv_ * this->re_ + that.fpv_ * that.re_) / fpv;
+      if (is_neg(temp))
+        temp = -temp;
+      re = temp + ROUNDING_ERROR;
+    }
+    return robust_fpt(fpv, re);
+  }
+
+  robust_fpt operator*(const robust_fpt &that) const {
+    floating_point_type fpv = this->fpv_ * that.fpv_;
+    relative_error_type re = this->re_ + that.re_ + ROUNDING_ERROR;
+    return robust_fpt(fpv, re);
+  }
+
+  robust_fpt operator/(const robust_fpt &that) const {
+    floating_point_type fpv = this->fpv_ / that.fpv_;
+    relative_error_type re = this->re_ + that.re_ + ROUNDING_ERROR;
+    return robust_fpt(fpv, re);
+  }
+
+  robust_fpt sqrt() const {
+    return robust_fpt(get_sqrt(fpv_),
+                      re_ * static_cast<relative_error_type>(0.5) +
+                      ROUNDING_ERROR);
+  }
+
+private:
+  floating_point_type fpv_;
+  relative_error_type re_;
+};
+
+template <typename T>
+const typename robust_fpt<T>::relative_error_type
+  robust_fpt<T>::ROUNDING_ERROR = 1;
+
+template <typename T>
+robust_fpt<T> get_sqrt(const robust_fpt<T>& that) {
+  return that.sqrt();
+}
+
+template <typename T>
+bool is_pos(const robust_fpt<T>& that) {
+  return that.has_pos_value();
+}
+
+template <typename T>
+bool is_neg(const robust_fpt<T>& that) {
+  return that.has_neg_value();
+}
+
+template <typename T>
+bool is_zero(const robust_fpt<T>& that) {
+  return that.has_zero_value();
+}
+
+// robust_dif consists of two not negative values: value1 and value2.
+// The resulting expression is equal to the value1 - value2.
+// Subtraction of a positive value is equivalent to the addition to value2
+// and subtraction of a negative value is equivalent to the addition to
+// value1. The structure implicitly avoids difference computation.
+template <typename T>
+class robust_dif {
+public:
+  robust_dif() :
+      positive_sum_(0),
+      negative_sum_(0) {}
+
+  robust_dif(const T &value) :
+      positive_sum_((value>0)?value:0),
+      negative_sum_((value<0)?-value:0) {}
+
+  robust_dif(const T &pos, const T &neg) :
+      positive_sum_(pos),
+      negative_sum_(neg) {}
+
+  T dif() const {
+    return positive_sum_ - negative_sum_;
+  }
+
+  T pos() const {
+    return positive_sum_;
+  }
+
+  T neg() const {
+    return negative_sum_;
+  }
+
+  robust_dif<T> operator-() const {
+    return robust_dif(negative_sum_, positive_sum_);
+  }
+
+  robust_dif<T> &operator+=(const T &val) {
+    if (!is_neg(val))
+      positive_sum_ += val;
+    else
+      negative_sum_ -= val;
+    return *this;
+  }
+
+  robust_dif<T> &operator+=(const robust_dif<T> &that) {
+    positive_sum_ += that.positive_sum_;
+    negative_sum_ += that.negative_sum_;
+    return *this;
+  }
+
+  robust_dif<T> &operator-=(const T &val) {
+    if (!is_neg(val))
+      negative_sum_ += val;
+    else
+      positive_sum_ -= val;
+    return *this;
+  }
+
+  robust_dif<T> &operator-=(const robust_dif<T> &that) {
+    positive_sum_ += that.negative_sum_;
+    negative_sum_ += that.positive_sum_;
+    return *this;
+  }
+
+  robust_dif<T> &operator*=(const T &val) {
+    if (!is_neg(val)) {
+      positive_sum_ *= val;
+      negative_sum_ *= val;
+    } else {
+      positive_sum_ *= -val;
+      negative_sum_ *= -val;
+      swap();
+    }
+    return *this;
+  }
+
+  robust_dif<T> &operator*=(const robust_dif<T> &that) {
+    T positive_sum = this->positive_sum_ * that.positive_sum_ +
+                     this->negative_sum_ * that.negative_sum_;
+    T negative_sum = this->positive_sum_ * that.negative_sum_ +
+                     this->negative_sum_ * that.positive_sum_;
+    positive_sum_ = positive_sum;
+    negative_sum_ = negative_sum;
+    return *this;
+  }
+
+  robust_dif<T> &operator/=(const T &val) {
+    if (!is_neg(val)) {
+      positive_sum_ /= val;
+      negative_sum_ /= val;
+    } else {
+      positive_sum_ /= -val;
+      negative_sum_ /= -val;
+      swap();
+    }
+    return *this;
+  }
+
+private:
+  void swap() {
+    (std::swap)(positive_sum_, negative_sum_);
+  }
+
+  T positive_sum_;
+  T negative_sum_;
+};
+
+template<typename T>
+robust_dif<T> operator+(const robust_dif<T>& lhs,
+                        const robust_dif<T>& rhs) {
+  return robust_dif<T>(lhs.pos() + rhs.pos(), lhs.neg() + rhs.neg());
+}
+
+template<typename T>
+robust_dif<T> operator+(const robust_dif<T>& lhs, const T& rhs) {
+  if (!is_neg(rhs)) {
+    return robust_dif<T>(lhs.pos() + rhs, lhs.neg());
+  } else {
+    return robust_dif<T>(lhs.pos(), lhs.neg() - rhs);
+  }
+}
+
+template<typename T>
+robust_dif<T> operator+(const T& lhs, const robust_dif<T>& rhs) {
+  if (!is_neg(lhs)) {
+    return robust_dif<T>(lhs + rhs.pos(), rhs.neg());
+  } else {
+    return robust_dif<T>(rhs.pos(), rhs.neg() - lhs);
+  }
+}
+
+template<typename T>
+robust_dif<T> operator-(const robust_dif<T>& lhs,
+                        const robust_dif<T>& rhs) {
+  return robust_dif<T>(lhs.pos() + rhs.neg(), lhs.neg() + rhs.pos());
+}
+
+template<typename T>
+robust_dif<T> operator-(const robust_dif<T>& lhs, const T& rhs) {
+  if (!is_neg(rhs)) {
+    return robust_dif<T>(lhs.pos(), lhs.neg() + rhs);
+  } else {
+    return robust_dif<T>(lhs.pos() - rhs, lhs.neg());
+  }
+}
+
+template<typename T>
+robust_dif<T> operator-(const T& lhs, const robust_dif<T>& rhs) {
+  if (!is_neg(lhs)) {
+    return robust_dif<T>(lhs + rhs.neg(), rhs.pos());
+  } else {
+    return robust_dif<T>(rhs.neg(), rhs.pos() - lhs);
+  }
+}
+
+template<typename T>
+robust_dif<T> operator*(const robust_dif<T>& lhs,
+                        const robust_dif<T>& rhs) {
+  T res_pos = lhs.pos() * rhs.pos() + lhs.neg() * rhs.neg();
+  T res_neg = lhs.pos() * rhs.neg() + lhs.neg() * rhs.pos();
+  return robust_dif<T>(res_pos, res_neg);
+}
+
+template<typename T>
+robust_dif<T> operator*(const robust_dif<T>& lhs, const T& val) {
+  if (!is_neg(val)) {
+    return robust_dif<T>(lhs.pos() * val, lhs.neg() * val);
+  } else {
+    return robust_dif<T>(-lhs.neg() * val, -lhs.pos() * val);
+  }
+}
+
+template<typename T>
+robust_dif<T> operator*(const T& val, const robust_dif<T>& rhs) {
+  if (!is_neg(val)) {
+    return robust_dif<T>(val * rhs.pos(), val * rhs.neg());
+  } else {
+    return robust_dif<T>(-val * rhs.neg(), -val * rhs.pos());
+  }
+}
+
+template<typename T>
+robust_dif<T> operator/(const robust_dif<T>& lhs, const T& val) {
+  if (!is_neg(val)) {
+    return robust_dif<T>(lhs.pos() / val, lhs.neg() / val);
+  } else {
+    return robust_dif<T>(-lhs.neg() / val, -lhs.pos() / val);
+  }
+}
+
+// Used to compute expressions that operate with sqrts with predefined
+// relative error. Evaluates expressions of the next type:
+// sum(i = 1 .. n)(A[i] * sqrt(B[i])), 1 <= n <= 4.
+template <typename _int, typename _fpt, typename _converter>
+class robust_sqrt_expr {
+public:
+  static const unsigned int EVAL1_MAX_RELATIVE_ERROR;
+  static const unsigned int EVAL2_MAX_RELATIVE_ERROR;
+  static const unsigned int EVAL3_MAX_RELATIVE_ERROR;
+  static const unsigned int EVAL4_MAX_RELATIVE_ERROR;
+
+  // Evaluates expression (re = 4 EPS):
+  // A[0] * sqrt(B[0]).
+  _fpt eval1(_int *A, _int *B) {
+    _fpt a = convert(A[0]);
+    _fpt b = convert(B[0]);
+    return a * get_sqrt(b);
+  }
+
+  // Evaluates expression (re = 7 EPS):
+  // A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]).
+  _fpt eval2(_int *A, _int *B) {
+    _fpt a = eval1(A, B);
+    _fpt b = eval1(A + 1, B + 1);
+    if ((!is_neg(a) && !is_neg(b)) ||
+        (!is_pos(a) && !is_pos(b)))
+      return a + b;
+    return convert(A[0] * A[0] * B[0] - A[1] * A[1] * B[1]) / (a - b);
+  }
+
+  // Evaluates expression (re = 16 EPS):
+  // A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]) + A[2] * sqrt(B[2]).
+  _fpt eval3(_int *A, _int *B) {
+    _fpt a = eval2(A, B);
+    _fpt b = eval1(A + 2, B + 2);
+    if ((!is_neg(a) && !is_neg(b)) ||
+        (!is_pos(a) && !is_pos(b)))
+      return a + b;
+    tA[3] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] - A[2] * A[2] * B[2];
+    tB[3] = 1;
+    tA[4] = A[0] * A[1] * 2;
+    tB[4] = B[0] * B[1];
+    return eval2(tA + 3, tB + 3) / (a - b);
+  }
+
+
+  // Evaluates expression (re = 25 EPS):
+  // A[0] * sqrt(B[0]) + A[1] * sqrt(B[1]) +
+  // A[2] * sqrt(B[2]) + A[3] * sqrt(B[3]).
+  _fpt eval4(_int *A, _int *B) {
+    _fpt a = eval2(A, B);
+    _fpt b = eval2(A + 2, B + 2);
+    if ((!is_neg(a) && !is_neg(b)) ||
+        (!is_pos(a) && !is_pos(b)))
+      return a + b;
+    tA[0] = A[0] * A[0] * B[0] + A[1] * A[1] * B[1] -
+            A[2] * A[2] * B[2] - A[3] * A[3] * B[3];
+    tB[0] = 1;
+    tA[1] = A[0] * A[1] * 2;
+    tB[1] = B[0] * B[1];
+    tA[2] = A[2] * A[3] * -2;
+    tB[2] = B[2] * B[3];
+    return eval3(tA, tB) / (a - b);
+  }
+
+private:
+  _int tA[5];
+  _int tB[5];
+  _converter convert;
+};
+
+template <typename _int, typename _fpt, typename _converter>
+const unsigned int robust_sqrt_expr<_int, _fpt, _converter>::EVAL1_MAX_RELATIVE_ERROR = 4;
+template <typename _int, typename _fpt, typename _converter>
+const unsigned int robust_sqrt_expr<_int, _fpt, _converter>::EVAL2_MAX_RELATIVE_ERROR = 7;
+template <typename _int, typename _fpt, typename _converter>
+const unsigned int robust_sqrt_expr<_int, _fpt, _converter>::EVAL3_MAX_RELATIVE_ERROR = 16;
+template <typename _int, typename _fpt, typename _converter>
+const unsigned int robust_sqrt_expr<_int, _fpt, _converter>::EVAL4_MAX_RELATIVE_ERROR = 25;
+}  // detail
+}  // polygon
+}  // boost
+
+#endif  // BOOST_POLYGON_DETAIL_VORONOI_ROBUST_FPT
Added: trunk/boost/polygon/detail/voronoi_structures.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/detail/voronoi_structures.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,451 @@
+// Boost.Polygon library detail/voronoi_structures.hpp header file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES
+#define BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES
+
+#include <list>
+#include <queue>
+#include <vector>
+
+namespace boost {
+namespace polygon {
+namespace detail {
+
+// Cartesian 2D point data structure.
+template <typename T>
+class point_2d {
+public:
+  typedef T coordinate_type;
+
+  point_2d() {}
+
+  point_2d(coordinate_type x, coordinate_type y) :
+      x_(x),
+      y_(y) {}
+
+  bool operator==(const point_2d &that) const {
+    return (this->x_ == that.x()) && (this->y_ == that.y());
+  }
+
+  bool operator!=(const point_2d &that) const {
+    return (this->x_ != that.x()) || (this->y_ != that.y());
+  }
+
+  coordinate_type x() const {
+    return x_;
+  }
+
+  coordinate_type y() const {
+    return y_;
+  }
+
+  point_2d& x(coordinate_type x) {
+    x_ = x;
+    return *this;
+  }
+
+  point_2d& y(coordinate_type y) {
+    y_ = y;
+    return *this;
+  }
+
+private:
+  coordinate_type x_;
+  coordinate_type y_;
+};
+
+// Site event type.
+// Occurs when the sweepline sweeps over one of the initial sites:
+//   1) point site;
+//   2) start-point of the segment site;
+//   3) endpoint of the segment site.
+// Implicit segment direction is defined: the start-point of
+// the segment compares less than its endpoint.
+// Each input segment is divided onto two site events:
+//   1) One going from the start-point to the endpoint
+//      (is_inverse_ = false);
+//   2) Another going from the endpoint to the start-point
+//      (is_inverse_ = true).
+// In beach line data structure segment sites of the first
+// type precede sites of the second type for the same segment.
+// Variables:
+//   point0_ - point site or segment's start-point;
+//   point1_ - segment's endpoint if site is a segment;
+//   index_ - the last bit encodes if the site is inverse;
+//            the last-1 bit encodes initial site direction;
+//            other bits encode site event index among the other site events.
+// Note: for all the sites is_inverse_ flag is equal to false by default.
+template <typename T>
+class site_event {
+public:
+  typedef T coordinate_type;
+  typedef point_2d<T> point_type;
+
+  site_event() :
+      point0_(0, 0),
+      point1_(0, 0),
+      site_index_(0) {}
+
+  site_event(coordinate_type x, coordinate_type y) :
+      point0_(x, y),
+      point1_(x, y),
+      site_index_(0) {}
+
+  site_event(const point_type &point) :
+      point0_(point),
+      point1_(point),
+      site_index_(0) {}
+
+  site_event(coordinate_type x1, coordinate_type y1,
+             coordinate_type x2, coordinate_type y2):
+      point0_(x1, y1),
+      point1_(x2, y2),
+      site_index_(0) {}
+
+  site_event(const point_type &point1, const point_type &point2) :
+      point0_(point1),
+      point1_(point2),
+      site_index_(0) {}
+
+  bool operator==(const site_event &that) const {
+    return (this->point0_ == that.point0_) &&
+           (this->point1_ == that.point1_) &&
+           (this->site_index_ == that.site_index_);
+  }
+
+  bool operator!=(const site_event &that) const {
+    return (this->point0_ != that.point0_) ||
+           (this->point1_ != that.point1_) ||
+           (this->site_index_ != that.site_index_);
+  }
+
+  coordinate_type x(bool oriented = false) const {
+    return x0(oriented);
+  }
+
+  coordinate_type y(bool oriented = false) const {
+    return y0(oriented);
+  }
+
+  coordinate_type x0(bool oriented = false) const {
+    if (!oriented)
+      return point0_.x();
+    return is_inverse() ? point1_.x() : point0_.x();
+  }
+
+  coordinate_type y0(bool oriented = false) const {
+    if (!oriented)
+      return point0_.y();
+    return is_inverse() ? point1_.y() : point0_.y();
+  }
+
+  coordinate_type x1(bool oriented = false) const {
+    if (!oriented)
+      return point1_.x();
+    return is_inverse() ? point0_.x() : point1_.x();
+  }
+
+  coordinate_type y1(bool oriented = false) const {
+    if (!oriented)
+      return point1_.y();
+    return is_inverse() ? point0_.y() : point1_.y();
+  }
+
+  const point_type &point0(bool oriented = false) const {
+    if (!oriented)
+      return point0_;
+    return is_inverse() ? point1_ : point0_;
+  }
+
+  const point_type &point1(bool oriented = false) const {
+    if (!oriented)
+      return point1_;
+    return is_inverse() ? point0_ : point1_;
+  }
+
+  site_event& index(int index) {
+    site_index_ = (index << 2) + (site_index_ & 3);
+    return *this;
+  }
+
+  site_event& inverse() {
+    site_index_ ^= IS_INVERSE;
+    return *this;
+  }
+
+  site_event& change_initial_direction() {
+    site_index_ ^= HAS_INITIAL_DIRECTION;
+    return *this;
+  }
+
+  size_t index() const {
+    return site_index_ >> 2;
+  }
+
+  bool is_point() const {
+    return point0_.x() == point1_.x() && point0_.y() == point1_.y();
+  }
+
+  bool is_segment() const {
+    return point0_.x() != point1_.x() || point0_.y() != point1_.y();
+  }
+
+  bool is_inverse() const {
+    return (site_index_ & IS_INVERSE) ? true : false;
+  }
+
+  bool is_initial() const {
+    return (site_index_ & HAS_INITIAL_DIRECTION) ? false : true;
+  }
+
+  bool has_initial_direction() const {
+    return is_inverse() ^ is_initial();
+  }
+
+private:
+  enum kBits {
+    IS_INVERSE = 1,
+    HAS_INITIAL_DIRECTION = 2
+  };
+
+  point_type point0_;
+  point_type point1_;
+  unsigned int site_index_;
+};
+
+// Circle event type.
+// Occurs when the sweepline sweeps over the rightmost point of the Voronoi
+// circle (with the center at the intersection point of the bisectors).
+// Circle event is made of the two consecutive nodes in the beach line data
+// structure. In case another node was inserted during algorithm execution
+// between the given two nodes circle event becomes inactive.
+// Variables:
+//   center_x_ - center x-coordinate;
+//   center_y_ - center y-coordinate;
+//   lower_x_ - leftmost x-coordinate;
+//   is_active_ - states whether circle event is still active.
+// NOTE: lower_y coordinate is always equal to center_y.
+template <typename T>
+class circle_event {
+public:
+  typedef T coordinate_type;
+
+  circle_event() : is_active_(true) {}
+
+  circle_event(coordinate_type c_x,
+               coordinate_type c_y,
+               coordinate_type lower_x) :
+      center_x_(c_x),
+      center_y_(c_y),
+      lower_x_(lower_x),
+      is_active_(true) {}
+
+  coordinate_type x() const {
+    return center_x_;
+  }
+
+  circle_event& x(coordinate_type center_x) {
+    center_x_ = center_x;
+    return *this;
+  }
+
+  coordinate_type y() const {
+    return center_y_;
+  }
+
+  circle_event& y(coordinate_type center_y) {
+    center_y_ = center_y;
+    return *this;
+  }
+
+  coordinate_type lower_x() const {
+    return lower_x_;
+  }
+
+  circle_event& lower_x(coordinate_type lower_x) {
+    lower_x_ = lower_x;
+    return *this;
+  }
+
+  coordinate_type lower_y() const {
+    return center_y_;
+  }
+
+  bool is_active() const {
+    return is_active_;
+  }
+
+  circle_event& deactivate() {
+    is_active_ = false;
+    return *this;
+  }
+
+private:
+  coordinate_type center_x_;
+  coordinate_type center_y_;
+  coordinate_type lower_x_;
+  bool is_active_;
+};
+
+// Event queue data structure, holds circle events.
+// During algorithm run, some of the circle events disappear (become
+// inactive). Priority queue data structure doesn't support
+// iterators (there is no direct ability to modify its elements).
+// Instead list is used to store all the circle events and priority queue
+// of the iterators to the list elements is used to keep the correct circle
+// events ordering.
+template <typename T, typename Predicate>
+class ordered_queue {
+public:
+  ordered_queue() {}
+
+  bool empty() const {
+    return c_.empty();
+  }
+
+  const T &top() const {
+    return *c_.top();
+  }
+
+  void pop() {
+    list_iterator_type it = c_.top();
+    c_.pop();
+    c_list_.erase(it);
+  }
+
+  T &push(const T &e) {
+    c_list_.push_front(e);
+    c_.push(c_list_.begin());
+    return c_list_.front();
+  }
+
+  void clear() {
+    while (!c_.empty())
+        c_.pop();
+    c_list_.clear();
+  }
+
+private:
+  typedef typename std::list<T>::iterator list_iterator_type;
+
+  struct comparison {
+    bool operator() (const list_iterator_type &it1,
+                     const list_iterator_type &it2) const {
+      return cmp_(*it1, *it2);
+    }
+    Predicate cmp_;
+  };
+
+  std::priority_queue< list_iterator_type,
+                       std::vector<list_iterator_type>,
+                       comparison > c_;
+  std::list<T> c_list_;
+
+  //Disallow copy constructor and operator=
+  ordered_queue(const ordered_queue&);
+  void operator=(const ordered_queue&);
+};
+
+// Represents a bisector node made by two arcs that correspond to the left
+// and right sites. Arc is defined as a curve with points equidistant from
+// the site and from the sweepline. If the site is a point then arc is
+// a parabola, otherwise it's a line segment. A segment site event will
+// produce different bisectors based on its direction.
+// In general case two sites will create two opposite bisectors. That's
+// why the order of the sites is important to define the unique bisector.
+// The one site is considered to be newer than the other one if it was
+// processed by the algorithm later (has greater index).
+template <typename Site>
+class beach_line_node_key {
+public:
+  typedef Site site_type;
+
+  // Constructs degenerate bisector, used to search an arc that is above
+  // the given site. The input to the constructor is the new site point.
+  explicit beach_line_node_key(const site_type &new_site) :
+      left_site_(new_site),
+      right_site_(new_site) {}
+
+  // Constructs a new bisector. The input to the constructor is the two
+  // sites that create the bisector. The order of sites is important.
+  beach_line_node_key(const site_type &left_site,
+                      const site_type &right_site) :
+      left_site_(left_site),
+      right_site_(right_site) {}
+
+  const site_type &left_site() const {
+    return left_site_;
+  }
+
+  site_type &left_site() {
+    return left_site_;
+  }
+
+  beach_line_node_key& left_site(const site_type &site) {
+    left_site_ = site;
+    return *this;
+  }
+
+  const site_type &right_site() const {
+    return right_site_;
+  }
+
+  site_type &right_site() {
+    return right_site_;
+  }
+
+  beach_line_node_key& right_site(const site_type &site) {
+    right_site_ = site;
+    return *this;
+  }
+
+private:
+  site_type left_site_;
+  site_type right_site_;
+};
+
+// Represents edge data structure from the Voronoi output, that is
+// associated as a value with beach line bisector in the beach
+// line. Contains pointer to the circle event in the circle event
+// queue if the edge corresponds to the right bisector of the circle event.
+template <typename Edge, typename Circle>
+class beach_line_node_data {
+public:
+  explicit beach_line_node_data(Edge *new_edge) :
+      circle_event_(NULL),
+      edge_(new_edge) {}
+
+  Circle *circle_event() const {
+    return circle_event_;
+  }
+
+  beach_line_node_data& circle_event(Circle *circle_event) {
+    circle_event_ = circle_event;
+    return *this;
+  }
+
+  Edge *edge() const {
+    return edge_;
+  }
+
+  beach_line_node_data& edge(Edge *new_edge) {
+    edge_ = new_edge;
+    return *this;
+  }
+
+private:
+  Circle *circle_event_;
+  Edge *edge_;
+};
+}  // detail
+}  // polygon
+}  // boost
+
+#endif  // BOOST_POLYGON_DETAIL_VORONOI_STRUCTURES
Deleted: trunk/boost/polygon/directed_line_segment_concept.hpp
==============================================================================
--- trunk/boost/polygon/directed_line_segment_concept.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
+++ (empty file)
@@ -1,453 +0,0 @@
-/*
-  Copyright 2008 Intel Corporation
- 
-  Use, modification and distribution are subject to the Boost Software License,
-  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-  http://www.boost.org/LICENSE_1_0.txt).
-*/
-#ifndef BOOST_POLYGON_DIRECTED_LINE_SEGMENT_CONCEPT_HPP
-#define BOOST_POLYGON_DIRECTED_LINE_SEGMENT_CONCEPT_HPP
-#include "isotropy.hpp"
-#include "directed_line_segment_data.hpp"
-#include "directed_line_segment_traits.hpp"
-#include "rectangle_concept.hpp"
-#include "detail/polygon_arbitrary_formation.hpp"
-
-namespace boost { namespace polygon{
-  struct directed_line_segment_concept {};
- 
-  template <typename T>
-  struct is_directed_line_segment_concept { typedef gtl_no type; };
-  template <>
-  struct is_directed_line_segment_concept<directed_line_segment_concept> { typedef gtl_yes type; };
-
-  template <typename T>
-  struct is_mutable_directed_line_segment_concept { typedef gtl_no type; };
-  template <>
-  struct is_mutable_directed_line_segment_concept<directed_line_segment_concept> { typedef gtl_yes type; };
-
-  template <typename T, typename CT>
-  struct directed_line_segment_distance_type_by_concept { typedef void type; };
-  template <typename T>
-  struct directed_line_segment_distance_type_by_concept<T, gtl_yes> { 
-    typedef typename coordinate_traits<typename directed_line_segment_traits<T>::coordinate_type>::coordinate_distance type; };
-
-  template <typename T>
-  struct directed_line_segment_distance_type {
-      typedef typename directed_line_segment_distance_type_by_concept<
-            T, typename is_directed_line_segment_concept<typename geometry_concept<T>::type>::type>::type type;
-  };
-
-  template <typename T, typename CT>
-  struct directed_line_segment_point_type_by_concept { typedef void type; };
-  template <typename T>
-  struct directed_line_segment_point_type_by_concept<T, gtl_yes> { 
-    typedef typename directed_line_segment_traits<T>::point_type type; };
-
-  template <typename T>
-  struct directed_line_segment_point_type {
-      typedef typename directed_line_segment_point_type_by_concept<
-            T, typename is_directed_line_segment_concept<typename geometry_concept<T>::type>::type>::type type;
-  };
-
-  template <typename T, typename CT>
-  struct directed_line_segment_coordinate_type_by_concept { typedef void type; };
-  template <typename T>
-  struct directed_line_segment_coordinate_type_by_concept<T, gtl_yes> { 
-    typedef typename directed_line_segment_traits<T>::coordinate_type type; };
-
-  template <typename T>
-  struct directed_line_segment_coordinate_type {
-      typedef typename directed_line_segment_coordinate_type_by_concept<
-            T, typename is_directed_line_segment_concept<typename geometry_concept<T>::type>::type>::type type;
-  };
-
-  template <typename T>
-  typename directed_line_segment_point_type<T>::type
-  get(const T& segment, direction_1d dir,
-  typename enable_if<typename gtl_if<typename is_directed_line_segment_concept<typename geometry_concept<T>::type>::type>::type>::type * = 0
-  ) {
-    return directed_line_segment_traits<T>::get(segment, dir); 
-  }
-
-  template <typename T, typename point_type>
-  void 
-  set(T& segment, direction_1d dir, point_type value,
-  typename enable_if<typename is_mutable_directed_line_segment_concept<typename geometry_concept<T>::type>::type>::type * = 0
-  ) {
-    directed_line_segment_mutable_traits<T>::set(segment, dir, value); 
-  }
-  
-  template <typename T, typename T2, typename T3>
-  T
-  construct(T2 low_value, T3 high_value,
-            typename enable_if<typename is_mutable_directed_line_segment_concept<typename geometry_concept<T>::type>::type>::type * = 0
-  ) {
-    return directed_line_segment_mutable_traits<T>::construct(low_value, high_value); 
-  }
-  
-  template <typename T, typename T2>
-  T
-  copy_construct(const T2& segment,
-  typename enable_if< typename gtl_and<typename is_mutable_directed_line_segment_concept<typename geometry_concept<T>::type>::type,
-  typename is_directed_line_segment_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
-  ) {
-    return construct<T>
-      (get(segment, LOW ),
-       get(segment, HIGH));
-  }
-
-  template <typename T1, typename T2>
-  T1 &
-  assign(T1& lvalue, const T2& rvalue,
-  typename enable_if< typename gtl_and< typename is_mutable_directed_line_segment_concept<typename geometry_concept<T1>::type>::type,
-  typename is_directed_line_segment_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0) {
-    lvalue = copy_construct<T1>(rvalue);
-    return lvalue;
-  }
-
-  template <typename T, typename T2>
-  bool 
-  equivalence(const T& segment1, const T2& segment2,
-  typename enable_if< typename gtl_and< typename is_directed_line_segment_concept<typename geometry_concept<T>::type>::type,
-  typename is_directed_line_segment_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
-  ) {
-    return get(segment1, LOW) ==
-      get(segment2, LOW) &&
-      get(segment1, HIGH) ==
-      get(segment2, HIGH); 
-  }
-  
-  struct y_dls_on_above_or_below : gtl_yes {};
-
-  //-1 for below, 0 for on and 1 for above
-  template <typename segment_type>
-  typename enable_if< typename gtl_and< y_dls_on_above_or_below, typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type >::type, bool>::type 
-  on_above_or_below(const segment_type& segment,
-                    typename directed_line_segment_traits<segment_type>::point_type value) {
-    typedef polygon_arbitrary_formation<typename directed_line_segment_traits<segment_type>::coordinate_type> paf;
-    typename paf::Point pt, l, h;
-    assign(pt, value);
-    assign(l, low(segment));
-    assign(h, high(segment));
-    return paf::on_above_or_below(pt, typename paf::half_edge(l, h));
-  }
-
-  struct y_dls_contains : gtl_yes {};
-
-  template <typename segment_type>
-  typename enable_if< typename gtl_and< y_dls_contains, typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type >::type, bool>::type 
-  contains(const segment_type& segment,
-           typename directed_line_segment_traits<segment_type>::point_type value, 
-           bool consider_touch = true ) {
-    if(on_above_or_below(segment, value) == 0) {
-      rectangle_data<typename directed_line_segment_traits<segment_type>::coordinate_type> rect;
-      set_points(rect, low(segment), high(segment));
-      if(area(rect) == 0.0) {
-        if(!consider_touch) {
-          return !equivalence(value, low(segment)) && !equivalence(value, high(segment));
-        }
-      }
-      return contains(rect, value, consider_touch);
-    }
-    return false;
-  }
-  
-  template <typename segment_type, typename segment_type_2>
-  bool 
-  contains(const segment_type& segment,
-           const segment_type_2& value, bool consider_touch = true,
-           typename enable_if< typename gtl_and< typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type,
-           typename is_directed_line_segment_concept<typename geometry_concept<segment_type_2>::type>::type>::type>::type * = 0
-           ) {
-    return contains(segment, get(value, LOW), consider_touch) &&
-      contains(segment, get(value, HIGH), consider_touch);
-  }
-  
-  // get the low point
-  template <typename segment_type>
-  typename directed_line_segment_point_type<segment_type>::type 
-  low(const segment_type& segment,
-  typename enable_if< typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type * = 0
-  ) { return get(segment, LOW); }
-
-  // get the high point
-  template <typename segment_type>
-  typename directed_line_segment_point_type<segment_type>::type 
-  high(const segment_type& segment,
-  typename enable_if< typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type * = 0
-  ) { return get(segment, HIGH); }
-
-  // get the center point
-  template <typename segment_type>
-  typename directed_line_segment_point_type<segment_type>::type
-  center(const segment_type& segment,
-  typename enable_if< typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type * = 0
-  ) { 
-    return construct<typename directed_line_segment_traits<segment_type>::point_type>((x(high(segment)) + x(low(segment)))/2,
-                                                                                      (y(high(segment)) + y(low(segment)))/2); 
-
-  }
-
-  struct y_dls_low : gtl_yes {};
-
-  // set the low point to v
-  template <typename segment_type>
-  typename enable_if<typename gtl_and<y_dls_low, typename is_mutable_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type, void>::type 
-  low(segment_type& segment,
-      typename directed_line_segment_traits<segment_type>::point_type v) { set(segment, LOW, v); }
-  
-  struct y_dls_high : gtl_yes {};
-
-  // set the high coordinate to v
-  template <typename segment_type>
-  typename enable_if<typename gtl_and<y_dls_high, typename is_mutable_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type, void>::type 
-  high(segment_type& segment,
-      typename directed_line_segment_traits<segment_type>::point_type v) { set(segment, HIGH, v); }
-  
-  template <typename segment_type>
-  typename directed_line_segment_distance_type<segment_type>::type 
-  length(const segment_type& segment,
-  typename enable_if< typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type * = 0
-  ) { return euclidean_distance(low(segment), high(segment)); }
-
-  struct y_dls_flip : gtl_yes {};
-
-  struct y_dls_scale_up : gtl_yes {};
-
-  // scale segment by factor
-  template <typename segment_type>
-  typename enable_if<typename gtl_and<y_dls_scale_up, typename is_mutable_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type, segment_type>::type &
-  scale_up(segment_type& segment, 
-           typename coordinate_traits<typename directed_line_segment_traits<segment_type>::coordinate_type>::unsigned_area_type factor) {
-    typename directed_line_segment_point_type<segment_type>::type l = low(segment), h = high(segment);
-    low(segment, scale_up(l, factor));
-    high(segment, scale_up(h, factor));
-    return segment;
-  }
-
-  struct y_dls_scale_down : gtl_yes {};
-
-  template <typename segment_type>
-  typename enable_if<typename gtl_and<y_dls_scale_down, typename is_mutable_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type, segment_type>::type &
-  scale_down(segment_type& segment, 
-             typename coordinate_traits<typename directed_line_segment_traits<segment_type>::coordinate_type>::unsigned_area_type factor) {
-    typename directed_line_segment_point_type<segment_type>::type l = low(segment), h = high(segment);
-    low(segment, scale_down(l, factor));
-    high(segment, scale_down(h, factor));
-    return segment;
-  }
-
-  struct y_dls_scale : gtl_yes {};
-
-  template <typename segment_type, typename scaling_type>
-  typename enable_if<typename gtl_and<y_dls_scale, typename is_mutable_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type, segment_type>::type &
-  scale(segment_type& segment, scaling_type factor) {
-    typename directed_line_segment_point_type<segment_type>::type l = low(segment), h = high(segment);
-    low(segment, scale(l, factor));
-    high(segment, scale(h, factor));
-    return segment;
-  }
-
-
-  struct y_dls_transform : gtl_yes {};
-
-  template <typename segment_type, typename transform_type>
-  typename enable_if<typename gtl_and<y_dls_transform, typename is_mutable_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type, segment_type>::type &
-  transform(segment_type& segment, const transform_type& val) {
-    typename directed_line_segment_point_type<segment_type>::type l = low(segment), h = high(segment);
-    low(segment, transform(l, val));
-    high(segment, transform(h, val));
-    return segment;
-  }  
-  // move segment by delta
-  template <typename segment_type>
-  segment_type&
-  move(segment_type& segment, orientation_2d orient,
-       typename directed_line_segment_coordinate_type<segment_type>::type displacement,
-       typename enable_if<typename is_mutable_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type * = 0
-       ) {
-    typename directed_line_segment_point_type<segment_type>::type l = low(segment), h = high(segment);
-    low(segment, move(l, orient, displacement));
-    high(segment, move(h, orient, displacement));
-    return segment;
-  }
-  
-  struct y_dls_convolve : gtl_yes {};
-
-  // convolve this with b
-  template <typename segment_type>
-  typename enable_if<typename gtl_and<y_dls_convolve, typename is_mutable_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type, segment_type>::type &
-  convolve(segment_type& segment,
-           const typename directed_line_segment_traits<segment_type>::point_type& b) {
-    typename directed_line_segment_point_type<segment_type>::type l = low(segment), h = high(segment);
-    low(segment, convolve(l, b));
-    high(segment, convolve(h, b));
-    return segment;
-  }
-
-  struct y_dls_deconvolve : gtl_yes {};
-
-  // deconvolve this with b
-  template <typename segment_type>
-  typename enable_if<typename gtl_and<y_dls_deconvolve, typename is_mutable_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type, segment_type>::type &
-  deconvolve(segment_type& segment,
-             const typename directed_line_segment_traits<segment_type>::point_type& b) {
-    typename directed_line_segment_point_type<segment_type>::type l = low(segment), h = high(segment);
-    low(segment, deconvolve(l, b));
-    high(segment, deconvolve(h, b));
-    return segment;
-  }
-
-  struct y_dls_e_dist1 : gtl_yes {};
-
-  // distance from a point to a segment
-  template <typename segment_type>
-  typename enable_if< typename gtl_and<y_dls_e_dist1, typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type>::type,
-      typename directed_line_segment_distance_type<segment_type>::type>::type
-  euclidean_distance(const segment_type& segment,
-                     typename directed_line_segment_traits<segment_type>::point_type position) {
-    typedef typename directed_line_segment_distance_type<segment_type>::type Unit;
-    Unit x1 = x(low(segment));
-    Unit y1 = y(low(segment));
-    Unit x2 = x(high(segment));
-    Unit y2 = y(high(segment));
-    Unit X = x(position);
-    Unit Y = y(position);
-    Unit A = X - x1;
-    Unit B = Y - y1;
-    Unit C = x2 - x1;
-    Unit D = y2 - y1;
-    Unit length_sq = C * C + D * D;
-    Unit param = (A * C + B * D)/length_sq;
-    if(param > 1.0) {
-      return euclidean_distance(high(segment), position);
-    } else if(param < 0.0) {
-      return euclidean_distance(low(segment), position);
-    } 
-    Unit denom = sqrt(length_sq);
-    if(denom == 0.0)
-      return 0.0;
-    Unit result = (A * D - C * B) / denom;
-    if(result < 0.0)
-      result *= -1;
-    return result;
-  }
-
-  struct y_dls_e_dist2 : gtl_yes {};
-  
-  // distance between two segments
-  template <typename segment_type, typename segment_type_2>
-  typename enable_if< 
-    typename gtl_and_3<y_dls_e_dist2, typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type,
-                       typename is_directed_line_segment_concept<typename geometry_concept<segment_type_2>::type>::type>::type,
-    typename directed_line_segment_distance_type<segment_type>::type>::type
-  euclidean_distance(const segment_type& segment,
-                     const segment_type_2& b) {
-    typename directed_line_segment_distance_type<segment_type>::type result1 = euclidean_distance(segment, low(b)),
-    result2 = euclidean_distance(segment, high(b));
-    if(result2 < result1) result1 = result2;
-    return result1;
-  }
-  
-  struct y_dls_e_intersects : gtl_yes {};
-
-  // check if Interval b intersects `this` Interval
-  template <typename segment_type, typename segment_type_2>
-  typename enable_if< typename gtl_and_3<y_dls_e_intersects, 
-                                         typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type, 
-                                         typename is_directed_line_segment_concept<typename geometry_concept<segment_type_2>::type>::type
-  >::type, bool> ::type 
-  intersects(const segment_type& segment, const segment_type_2& b, bool consider_touch = true) {
-    if(consider_touch) {
-      if(low(segment) == low(b) || low(segment) == high(b) || high(segment) == low(b) || high(segment) == high(b))
-        return true;
-    }
-    typedef polygon_arbitrary_formation<typename directed_line_segment_traits<segment_type>::coordinate_type> paf;
-    typename paf::Point l, h, l2, h2;
-    assign(l, low(segment));
-    assign(h, high(segment));
-    assign(l2, low(b));
-    assign(h2, high(b));
-    return paf::intersects(typename paf::half_edge(l, h), typename paf::half_edge(l2, h2));
-  }
-
-  struct y_dls_e_bintersect : gtl_yes {};
-
-  // check if Interval b partially overlaps `this` Interval
-  template <typename segment_type, typename segment_type_2>
-  typename enable_if< 
-    typename gtl_and_3<y_dls_e_bintersect, typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type,
-                       typename is_directed_line_segment_concept<typename geometry_concept<segment_type_2>::type>::type>::type,
-    bool>::type 
-  boundaries_intersect(const segment_type& segment, const segment_type_2& b, 
-                       bool consider_touch = true) {
-    return (contains(segment, low(b), consider_touch) || 
-            contains(segment, high(b), consider_touch)) &&
-      (contains(b, low(segment), consider_touch) || 
-       contains(b, high(segment), consider_touch));
-  }
-
-  struct y_dls_abuts1 : gtl_yes {};
-
-  // check if they are end to end
-  template <typename segment_type, typename segment_type_2>
-  typename enable_if< typename gtl_and_3<y_dls_abuts1, typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type,
-                                         typename is_directed_line_segment_concept<typename geometry_concept<segment_type_2>::type>::type>::type,
-                       bool>::type 
-  abuts(const segment_type& segment, const segment_type_2& b, direction_1d dir) {
-    return dir.to_int() ? equivalence(low(b) , high(segment)) : equivalence(low(segment) , high(b));
-  }
-
-  struct y_dls_abuts2 : gtl_yes {};
-
-  // check if they are end to end
-  template <typename segment_type, typename segment_type_2>
-  typename enable_if< 
-    typename gtl_and_3<y_dls_abuts2, typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type,
-                       typename is_directed_line_segment_concept<typename geometry_concept<segment_type_2>::type>::type>::type,
-    bool>::type 
-  abuts(const segment_type& segment, const segment_type_2& b) {
-    return abuts(segment, b, HIGH) || abuts(segment, b, LOW);
-  } 
-
-  struct y_dls_intersect : gtl_yes {};
-
-  // set point to the intersection of segment and b
-  template <typename point_type, typename segment_type, typename segment_type_2>
-    typename enable_if< typename gtl_and_4<y_dls_intersect, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type,
-      typename is_directed_line_segment_concept<typename geometry_concept<segment_type>::type>::type,
-      typename is_directed_line_segment_concept<typename geometry_concept<segment_type_2>::type>::type>::type,
-                       bool>::type 
-  intersection(point_type& intersection, const segment_type& segment, const segment_type_2& b, 
-               bool projected = false, bool round_closest = false) {
-    typedef polygon_arbitrary_formation<typename directed_line_segment_traits<segment_type>::coordinate_type> paf;
-    typename paf::Point pt;
-    typename paf::Point l, h, l2, h2;
-    assign(l, low(segment));
-    assign(h, high(segment));
-    assign(l2, low(b));
-    assign(h2, high(b));
-    typename paf::half_edge he1(l, h), he2(l2, h2);
-    typename paf::compute_intersection_pack pack;
-    if(pack.compute_intersection(pt, he1, he2, projected, round_closest)) {
-      assign(intersection, pt);
-      return true;
-    }
-    return false;
-  }
-
-  template <class T>
-  template <class T2>
-  directed_line_segment_data<T>& directed_line_segment_data<T>::operator=(const T2& rvalue) {
-    assign(*this, rvalue);
-    return *this;
-  }
-
-  template <typename T>
-  struct geometry_concept<directed_line_segment_data<T> > {
-    typedef directed_line_segment_concept type;
-  };
-}
-}
-#endif
Deleted: trunk/boost/polygon/directed_line_segment_data.hpp
==============================================================================
--- trunk/boost/polygon/directed_line_segment_data.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
+++ (empty file)
@@ -1,69 +0,0 @@
-/*
-  Copyright 2008 Intel Corporation
- 
-  Use, modification and distribution are subject to the Boost Software License,
-  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-  http://www.boost.org/LICENSE_1_0.txt).
-*/
-#ifndef BOOST_POLYGON_DIRECTED_LINE_SEGMENT_DATA_HPP
-#define BOOST_POLYGON_DIRECTED_LINE_SEGMENT_DATA_HPP
-#include "isotropy.hpp"
-#include "point_data.hpp"
-namespace boost { namespace polygon{
-  template <typename T>
-  class directed_line_segment_data {
-  public:
-    typedef T coordinate_type;
-    typedef point_data<T> point_type;
-    inline directed_line_segment_data()
-#ifndef BOOST_POLYGON_MSVC 
-      :points_() 
-#endif 
-    {} 
-    inline directed_line_segment_data(point_type low, point_type high)
-#ifndef BOOST_POLYGON_MSVC 
-      :points_() 
-#endif 
-    {
-      points_[LOW] = low; points_[HIGH] = high; 
-    }
-    inline directed_line_segment_data(const directed_line_segment_data& that)
-#ifndef BOOST_POLYGON_MSVC 
-      :points_() 
-#endif 
-    {
-      (*this) = that; 
-    }
-    inline directed_line_segment_data& operator=(const directed_line_segment_data& that) {
-      points_[0] = that.points_[0]; points_[1] = that.points_[1]; return *this; 
-    }
-    template <typename T2>
-    inline directed_line_segment_data& operator=(const T2& rvalue);
-    inline point_type get(direction_1d dir) const {
-      return points_[dir.to_int()]; 
-    }
-    inline point_type low() const { return points_[0]; }
-    inline point_type high() const { return points_[1]; }
-    inline bool operator==(const directed_line_segment_data& that) const {
-      return low() == that.low() && high() == that.high(); }
-    inline bool operator!=(const directed_line_segment_data& that) const {
-      return low() != that.low() || high() != that.high(); }
-    inline bool operator<(const directed_line_segment_data& that) const {
-      if(points_[0] < that.points_[0]) return true;
-      if(points_[0] > that.points_[0]) return false;
-      if(points_[1] < that.points_[1]) return true;
-      return false;
-    }
-    inline bool operator<=(const directed_line_segment_data& that) const { return !(that < *this); }
-    inline bool operator>(const directed_line_segment_data& that) const { return that < *this; }
-    inline bool operator>=(const directed_line_segment_data& that) const { return !((*this) < that); }
-  inline void set(direction_1d dir, point_type value) {
-    points_[dir.to_int()] = value; 
-  }
-private:
-  point_type points_[2]; 
-};
-
-}
-}
-#endif
Deleted: trunk/boost/polygon/directed_line_segment_set_data.hpp
==============================================================================
--- trunk/boost/polygon/directed_line_segment_set_data.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
+++ (empty file)
@@ -1,270 +0,0 @@
-/*
-  Copyright 2008 Intel Corporation
- 
-  Use, modification and distribution are subject to the Boost Software License,
-  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-  http://www.boost.org/LICENSE_1_0.txt).
-*/
-#ifndef BOOST_POLYGON_DIRECTED_LINE_SEGMENT_SET_DATA_HPP
-#define BOOST_POLYGON_DIRECTED_LINE_SEGMENT_SET_DATA_HPP
-
-namespace boost { namespace polygon{
-  template <typename T>
-  class directed_line_segment_set_data {
-  public:
-    typedef T coordinate_type;
-    typedef point_data<T> point_type;
-    typedef directed_line_segment_data<T> directed_line_segment_type;
-    typedef std::vector<directed_line_segment_type> value_type;
-    typedef typename std::vector<directed_line_segment_type>::const_iterator iterator_type;
-
-    inline directed_line_segment_set_data() : data_(), dirty_(false), unsorted_(false) {}
-    inline directed_line_segment_set_data(const directed_line_segment_set_data& that): 
-      data_(that.data_), dirty_(that.dirty_), unsorted_(that.unsorted_) {}
-    inline directed_line_segment_set_data& operator=(const directed_line_segment_set_data& that) {
-      if(this == &that) return *this;
-      data_ = that.data_;
-      dirty_ = that.dirty_;
-      unsorted_ = that.unsorted_;
-      return *this;
-    }
-    template <typename T2>
-    inline directed_line_segment_set_data& operator=(const T2& rvalue) {
-      data_.clear();
-      bool unsorted = !sorted(rvalue);
-      bool dirty = !dirty(rvalue);
-      insert(begin(rvalue), end(rvalue));
-      unsorted_ = unsorted;
-      dirty_ = dirty;
-      return *this;
-    }
-
-    inline bool operator==(const directed_line_segment_set_data& that) const {
-      clean();
-      that.clean();
-      sort();
-      that.sort();
-      return data_ == that.data_;
-    } 
-    inline bool operator!=(const directed_line_segment_set_data& that) const {
-      return !(*this == that);
-    }
-
-    template <typename iT>
-    inline void insert(iT begin_segments, iT end_segments) {
-      data_.clear();
-      for(; begin_segments != end_segments; ++begin_segments) {
-        insert(*begin_segments);
-      }
-    }
-
-    template <typename ST>
-    inline void insert(ST segment) {
-      unsorted_ = true;
-      dirty_ = true;
-      directed_line_segment_type tmp_seg;
-      assign(tmp_seg, segment);
-      data_.push_back(tmp_seg);
-    }
-
-    inline void clear() { data_.clear(); unsorted_ = false; dirty_ = false; }
-
-    inline iterator_type begin() const {
-      return data_.begin();
-    }
-
-    inline iterator_type end() const {
-      return data_.end();
-    }
-
-    const value_type& value() const {
-      return data_;
-    }
-
-    template <typename output_container>
-    inline void get(output_container& output) const {
-      for(std::size_t i = 0; i < size(); ++i) {
-        output.push_back(typename output_container::value_type());
-        assign(output.back(), data_[i]);
-      }
-    }
-
-    inline bool empty() const { return data_.empty(); }
-
-    inline std::size_t size() const { clean(); return data_.size(); }
-
-    inline std::size_t capacity() const { return data_.capacity(); }
-
-    inline void reserve(std::size_t size) { return data_.reserve(size); }
-
-    inline bool sorted() const { return !unsorted_; }
-
-    inline bool dirty() const { return dirty_; }
-
-    void clean() const {
-      typedef T Unit;
-      typedef typename scanline_base<Unit>::Point Point;
-      typedef typename scanline_base<Unit>::half_edge half_edge;
-      typedef int segment_id;
-      std::vector<std::pair<half_edge, segment_id> > half_edges;
-      std::vector<std::pair<half_edge, segment_id> > half_edges_out;
-      segment_id id = 0;
-      half_edges.reserve(data_.size());
-      for(iterator_type itr = begin(); itr != end(); ++itr) {
-        Point l = (*itr).low();
-        Point h = (*itr).high();
-        half_edges.push_back(std::make_pair(half_edge(l, h), id++));
-      }
-      half_edges_out.reserve(half_edges.size());
-      //apparently no need to pre-sort data when calling validate_scan
-      line_intersection<Unit>::validate_scan(half_edges_out, half_edges.begin(), half_edges.end());
-      value_type result;
-      result.reserve(half_edges_out.size());
-      for(std::size_t i = 0; i < half_edges_out.size(); ++i) {
-        id = half_edges_out[i].second;
-        Point l = half_edges_out[i].first.first;
-        Point h = half_edges_out[i].first.second;
-        directed_line_segment_type orig_seg = data_[id];
-        if(orig_seg.high() < orig_seg.low())
-          std::swap(l, h);
-        result.push_back(directed_line_segment_type(l, h));
-      }
-      std::swap(result, data_);
-      dirty_ = false;
-      unsorted_ = true;
-    };
-
-    void sort() const{
-      if(unsorted_) {
-        polygon_sort(data_.begin(), data_.end());
-        unsorted_ = false;
-      }
-    }
-
-    template <typename input_iterator_type>
-    void set(input_iterator_type input_begin, input_iterator_type input_end) {
-      clear();
-      reserve(std::distance(input_begin,input_end));
-      insert(input_begin, input_end);
-      dirty_ = true;
-      unsorted_ = true;
-    }
-
-    void set(const value_type& value) {
-      data_ = value; 
-      dirty_ = true;
-      unsorted_ = true;
-    }
-
-    template <typename rectangle_type>
-    bool extents(rectangle_type& rect) {
-      if(empty()) return false;
-      bool first_iteration = true;
-      for(iterator_type itr = begin();
-          itr != end(); ++itr) {
-        rectangle_type edge_box;
-        set_points(edge_box, (*itr).low(), (*itr).high());
-        if(first_iteration)
-          rect = edge_box;
-        else
-          encompass(rect, edge_box);
-        first_iteration = false;
-      }
-      return true;
-    }
-
-    template <typename transform_type>
-    inline directed_line_segment_set_data& 
-    transform(const transform_type& tr) {
-      for(typename value_type::iterator itr = data_.begin(); itr != data_.end(); ++itr) {
-        point_type l = (*itr).low();
-        point_type h = (*itr).high();
-        ::boost::polygon::transform(l, tr);
-        ::boost::polygon::transform(h, tr);
-        (*itr).low(l);
-        (*itr).high(h);
-      }
-      unsorted_ = true;
-      return *this;
-    }
-
-    inline directed_line_segment_set_data& 
-    scale_up(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) {
-      for(typename value_type::iterator itr = data_.begin(); itr != data_.end(); ++itr) {
-        point_type l = (*itr).low();
-        point_type h = (*itr).high();
-        ::boost::polygon::scale_up(l, factor);
-        ::boost::polygon::scale_up(h, factor);
-        (*itr).low(l);
-        (*itr).high(h);
-      }
-      return *this;
-    }
-    
-    inline directed_line_segment_set_data& 
-    scale_down(typename coordinate_traits<coordinate_type>::unsigned_area_type factor) {
-      for(typename value_type::iterator itr = data_.begin(); itr != data_.end(); ++itr) {
-        point_type l = (*itr).low();
-        point_type h = (*itr).high();
-        ::boost::polygon::scale_down(l, factor);
-        ::boost::polygon::scale_down(h, factor);
-        (*itr).low(l);
-        (*itr).high(h);
-      }
-      return *this;
-    }
-    
-    template <typename scaling_type>
-    inline directed_line_segment_set_data& scale(const scaling_type& scaling) {
-      for(typename value_type::iterator itr = data_.begin(); itr != data_.end(); ++itr) {
-        point_type l = (*itr).low();
-        point_type h = (*itr).high();
-        ::boost::polygon::scale(l, scaling);
-        ::boost::polygon::scale(h, scaling);
-        (*itr).low(l);
-        (*itr).high(h);
-      }
-      return *this;
-    }
-
-    template <typename cT>
-    std::size_t get_intersection_points(cT& output_points) const {
-      typedef T Unit;
-      typedef typename scanline_base<Unit>::Point Point;
-      typedef typename scanline_base<Unit>::half_edge half_edge;
-      typedef int segment_id;
-      std::vector<std::pair<half_edge, segment_id> > half_edges;
-      std::vector<std::pair<half_edge, segment_id> > half_edges_out;
-      segment_id id = 0;
-      half_edges.reserve(data_.size());
-      for(iterator_type itr = begin(); itr != end(); ++itr) {
-        Point l = (*itr).low();
-        Point h = (*itr).high();
-        half_edges.push_back(std::make_pair(half_edge(l, h), id++));
-      }
-      half_edges_out.reserve(half_edges.size());
-      std::vector<std::set<Point> > intersection_points(half_edges.size(), std::set<Point>());
-      line_intersection<Unit>::validate_scan_divide_and_conquer(intersection_points, half_edges.begin(), half_edges.end());
-      std::vector<Point> tmp_points;
-      for(std::size_t i = 0; i < intersection_points.size(); ++i) {
-        typename std::set<Point>::iterator itr2 = intersection_points[i].begin();
-        for(; itr2 != intersection_points[i].end(); ++itr2)
-          if(data_[i].low() != *itr2 && data_[i].high() != *itr2)
-            tmp_points.push_back(*itr2);
-      }
-      polygon_sort(tmp_points.begin(), tmp_points.end());
-      typename std::vector<Point>::iterator new_end = std::unique(tmp_points.begin(), tmp_points.end());
-      output_points.insert(output_points.end(), tmp_points.begin(), new_end);
-      return std::distance(tmp_points.begin(), new_end);
-    };
-
-
-private:
-    mutable value_type data_;
-    mutable bool dirty_;
-    mutable bool unsorted_;
-};
-
-}
-}
-#endif
Deleted: trunk/boost/polygon/directed_line_segment_traits.hpp
==============================================================================
--- trunk/boost/polygon/directed_line_segment_traits.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
+++ (empty file)
@@ -1,42 +0,0 @@
-/*
-  Copyright 2008 Intel Corporation
- 
-  Use, modification and distribution are subject to the Boost Software License,
-  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-  http://www.boost.org/LICENSE_1_0.txt).
-*/
-#ifndef BOOST_POLYGON_DIRECTED_LINE_SEGMENT_TRAITS_HPP
-#define BOOST_POLYGON_DIRECTED_LINE_SEGMENT_TRAITS_HPP
-namespace boost { namespace polygon{
-  template <typename T>
-  struct directed_line_segment_traits {
-    typedef typename T::coordinate_type coordinate_type;
-    typedef typename T::point_type point_type;
-
-    static inline point_type get(const T& segment, direction_1d dir) {
-      return segment.get(dir); 
-    }
-  };
-
-  template <typename T>
-  struct directed_line_segment_mutable_traits {
-    template <typename Point1>
-    static inline void set(T& segment, direction_1d dir, const Point1& value) {
-      typename directed_line_segment_traits<T>::point_type p1;
-      assign(p1, value);
-      segment.set(dir, value); 
-    }
-    
-    template <typename Point1, typename Point2>
-    static inline T construct(const Point1& low_value, 
-                              const Point2& high_value) {
-      typename directed_line_segment_traits<T>::point_type p1, p2; 
-      assign(p1, low_value);
-      assign(p2, high_value);
-      return T(p1, p2); 
-    }
-  };
-}
-}
-#endif
-
Modified: trunk/boost/polygon/interval_concept.hpp
==============================================================================
--- trunk/boost/polygon/interval_concept.hpp	(original)
+++ trunk/boost/polygon/interval_concept.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -47,65 +47,79 @@
             T, typename is_interval_concept<typename geometry_concept<T>::type>::type>::type type;
   };
 
+  struct y_i_get : gtl_yes {};
 
   template <typename T>
-  typename interval_coordinate_type<T>::type
-  get(const T& interval, direction_1d dir,
-  typename enable_if<typename gtl_if<typename is_interval_concept<typename geometry_concept<T>::type>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and<
+        y_i_get,
+        typename is_interval_concept<typename geometry_concept<T>::type>::type>::type,
+      typename interval_coordinate_type<T>::type>::type
+  get(const T& interval, direction_1d dir) {
     return interval_traits<T>::get(interval, dir); 
   }
 
+  struct y_i_set : gtl_yes {};
+
   template <typename T, typename coordinate_type>
-  void 
-  set(T& interval, direction_1d dir, coordinate_type value,
-  typename enable_if<typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and<
+        y_i_set,
+        typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type>::type,
+      void>::type
+  set(T& interval, direction_1d dir, coordinate_type value) {
     //this may need to be refined
     interval_mutable_traits<T>::set(interval, dir, value); 
     if(high(interval) < low(interval))
       interval_mutable_traits<T>::set(interval, dir.backward(), value);
   }
+
+  struct y_i_construct : gtl_yes {};
   
   template <typename T, typename T2, typename T3>
-  T
-  construct(T2 low_value, T3 high_value,
-            typename enable_if<typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and<
+        y_i_construct,
+        typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type>::type,
+      T>::type
+  construct(T2 low_value, T3 high_value) {
     if(low_value > high_value) std::swap(low_value, high_value);
     return interval_mutable_traits<T>::construct(low_value, high_value); 
   }
+
+  struct y_i_copy_construct : gtl_yes {};
   
   template <typename T, typename T2>
-  T
-  copy_construct(const T2& interval,
-  typename enable_if< typename gtl_and<typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type,
-  typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
-  ) {
-    return construct<T>
-      (get(interval, LOW ),
-       get(interval, HIGH));
+  typename enable_if< typename gtl_and_3<
+        y_i_copy_construct,
+        typename is_mutable_interval_concept<typename geometry_concept<T>::type>::type,
+        typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type,
+      T>::type
+  copy_construct(const T2& interval) {
+    return construct<T>(get(interval, LOW ), get(interval, HIGH));
   }
 
+  struct y_i_assign : gtl_yes {};
+
   template <typename T1, typename T2>
-  T1 &
-  assign(T1& lvalue, const T2& rvalue,
-  typename enable_if< typename gtl_and< typename is_mutable_interval_concept<typename geometry_concept<T1>::type>::type,
-  typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0) {
+  typename enable_if< typename gtl_and_3<
+        y_i_assign,
+        typename is_mutable_interval_concept<typename geometry_concept<T1>::type>::type,
+        typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type,
+      T1>::type &
+  assign(T1& lvalue, const T2& rvalue) {
     lvalue = copy_construct<T1>(rvalue);
     return lvalue;
   }
 
+  struct y_i_equivalence : gtl_yes {};
+
   template <typename T, typename T2>
-  bool 
-  equivalence(const T& interval1, const T2& interval2,
-  typename enable_if< typename gtl_and< typename is_interval_concept<typename geometry_concept<T>::type>::type,
-  typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
-  ) {
-    return get(interval1, LOW) ==
-      get(interval2, LOW) &&
-      get(interval1, HIGH) ==
-      get(interval2, HIGH); 
+  typename enable_if< typename gtl_and_3<
+        y_i_equivalence,
+        typename is_interval_concept<typename geometry_concept<T>::type>::type,
+        typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type,
+      bool>::type
+  equivalence(const T& interval1, const T2& interval2) {
+    return get(interval1, LOW) == get(interval2, LOW) &&
+           get(interval1, HIGH) == get(interval2, HIGH); 
   }
   
   struct y_i_contains : gtl_yes {};
@@ -113,7 +127,7 @@
   template <typename interval_type>
   typename enable_if< typename gtl_and< y_i_contains, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type >::type, bool>::type 
   contains(const interval_type& interval,
-           typename interval_traits<interval_type>::coordinate_type value, 
+           typename interval_coordinate_type<interval_type>::type value, 
            bool consider_touch = true ) {
     if(consider_touch) {
       return value <= high(interval) && value >= low(interval);
@@ -121,63 +135,85 @@
       return value < high(interval) && value > low(interval);
     }
   }
-  
+
+  struct y_i_contains2 : gtl_yes {};
+
   template <typename interval_type, typename interval_type_2>
-  bool 
+  typename enable_if< typename gtl_and_3<
+        y_i_contains2,
+        typename is_interval_concept<typename geometry_concept<interval_type>::type>::type,
+        typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
+      bool>::type
   contains(const interval_type& interval,
-           const interval_type_2& value, bool consider_touch = true,
-           typename enable_if< typename gtl_and< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type,
-           typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type>::type * = 0
-           ) {
+           const interval_type_2& value,
+           bool consider_touch = true) {
     return contains(interval, get(value, LOW), consider_touch) &&
       contains(interval, get(value, HIGH), consider_touch);
   }
-  
+
+  struct y_i_low : gtl_yes {};
+
   // get the low coordinate
   template <typename interval_type>
-  typename interval_traits<interval_type>::coordinate_type 
-  low(const interval_type& interval,
-  typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
-  ) { return get(interval, LOW); }
+  typename enable_if< typename gtl_and<
+        y_i_low,
+        typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
+      typename interval_coordinate_type<interval_type>::type>::type
+  low(const interval_type& interval) { return get(interval, LOW); }
+
+  struct y_i_high : gtl_yes {};
 
   // get the high coordinate
   template <typename interval_type>
-  typename interval_traits<interval_type>::coordinate_type 
-  high(const interval_type& interval,
-  typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
-  ) { return get(interval, HIGH); }
+  typename enable_if< typename gtl_and<
+        y_i_high,
+        typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
+      typename interval_coordinate_type<interval_type>::type>::type
+  high(const interval_type& interval) { return get(interval, HIGH); }
+
+  struct y_i_center : gtl_yes {};
 
   // get the center coordinate
   template <typename interval_type>
-  typename interval_traits<interval_type>::coordinate_type
-  center(const interval_type& interval,
-  typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
-  ) { return (high(interval) + low(interval))/2; }
+  typename enable_if< typename gtl_and<
+        y_i_center,
+        typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
+      typename interval_coordinate_type<interval_type>::type>::type
+  center(const interval_type& interval) { return (high(interval) + low(interval))/2; }
 
 
-  struct y_i_low : gtl_yes {};
+  struct y_i_low2 : gtl_yes {};
 
   // set the low coordinate to v
   template <typename interval_type>
-  typename enable_if<typename gtl_and<y_i_low, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, void>::type 
+  typename enable_if<typename gtl_and<
+        y_i_low2,
+        typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
+      void>::type 
   low(interval_type& interval,
-      typename interval_traits<interval_type>::coordinate_type v) { set(interval, LOW, v); }
+      typename interval_coordinate_type<interval_type>::type v) { set(interval, LOW, v); }
   
-  struct y_i_high : gtl_yes {};
+  struct y_i_high2 : gtl_yes {};
 
   // set the high coordinate to v
   template <typename interval_type>
-  typename enable_if<typename gtl_and<y_i_high, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, void>::type 
+  typename enable_if<typename gtl_and<
+        y_i_high2,
+        typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
+      void>::type 
   high(interval_type& interval,
-      typename interval_traits<interval_type>::coordinate_type v) { set(interval, HIGH, v); }
-  
+      typename interval_coordinate_type<interval_type>::type v) { set(interval, HIGH, v); }
+
+  struct y_i_delta : gtl_yes {};
+
   // get the magnitude of the interval
   template <typename interval_type>
-  typename interval_difference_type<interval_type>::type 
-  delta(const interval_type& interval,
-  typename enable_if< typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
-  ) { 
-    typedef typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::coordinate_difference diffT;
+  typename enable_if< typename gtl_and<
+        y_i_delta,
+        typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
+      typename interval_difference_type<interval_type>::type >::type
+  delta(const interval_type& interval) { 
+    typedef typename coordinate_traits<typename interval_coordinate_type<interval_type>::type>::coordinate_difference diffT;
     return (diffT)high(interval) - (diffT)low(interval); }
 
   struct y_i_flip : gtl_yes {};
@@ -186,8 +222,8 @@
   template <typename interval_type>
   typename enable_if<typename gtl_and<y_i_flip, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
   flip(interval_type& interval,
-       typename interval_traits<interval_type>::coordinate_type axis = 0) {
-    typename interval_traits<interval_type>::coordinate_type newLow, newHigh;
+       typename interval_coordinate_type<interval_type>::type axis = 0) {
+    typename interval_coordinate_type<interval_type>::type newLow, newHigh;
     newLow  = 2 * axis - high(interval);
     newHigh = 2 * axis - low(interval);
     low(interval, newLow);
@@ -201,8 +237,8 @@
   template <typename interval_type>
   typename enable_if<typename gtl_and<y_i_scale_up, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
   scale_up(interval_type& interval, 
-           typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::unsigned_area_type factor) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+           typename coordinate_traits<typename interval_coordinate_type<interval_type>::type>::unsigned_area_type factor) {
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit newHigh = high(interval) * (Unit)factor;
     low(interval, low(interval) * (Unit)factor);
     high(interval, (newHigh));
@@ -214,8 +250,8 @@
   template <typename interval_type>
   typename enable_if<typename gtl_and<y_i_scale_down, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
   scale_down(interval_type& interval, 
-             typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::unsigned_area_type factor) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+             typename coordinate_traits<typename interval_coordinate_type<interval_type>::type>::unsigned_area_type factor) {
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     typedef typename coordinate_traits<Unit>::coordinate_distance dt;
     Unit newHigh = scaling_policy<Unit>::round((dt)(high(interval)) / (dt)factor); 
     low(interval, scaling_policy<Unit>::round((dt)(low(interval)) / (dt)factor)); 
@@ -228,21 +264,23 @@
   template <typename interval_type>
   typename enable_if<typename gtl_and<y_i_scale, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
   scale(interval_type& interval, double factor) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit newHigh = scaling_policy<Unit>::round((double)(high(interval)) * factor);
     low(interval, scaling_policy<Unit>::round((double)low(interval)* factor));
     high(interval, (newHigh));
     return interval;
   }
-  
+
+  struct y_i_move : gtl_yes {};
+
   // move interval by delta
   template <typename interval_type>
-  interval_type&
-  move(interval_type& interval,
-       typename interval_difference_type<interval_type>::type displacement,
-       typename enable_if<typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type * = 0
-       ) {
-    typedef typename interval_traits<interval_type>::coordinate_type ctype;
+  typename enable_if< typename gtl_and<
+        y_i_move,
+        typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
+      interval_type>::type &
+  move(interval_type& interval, typename interval_difference_type<interval_type>::type displacement) {
+    typedef typename interval_coordinate_type<interval_type>::type ctype;
     typedef typename coordinate_traits<ctype>::coordinate_difference Unit;
     Unit len = delta(interval);
     low(interval, static_cast<ctype>(static_cast<Unit>(low(interval)) + displacement));
@@ -256,8 +294,8 @@
   template <typename interval_type>
   typename enable_if<typename gtl_and<y_i_convolve, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
   convolve(interval_type& interval,
-           typename interval_traits<interval_type>::coordinate_type b) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+           typename interval_coordinate_type<interval_type>::type b) {
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit newLow  = low(interval) + b;
     Unit newHigh = high(interval) + b;
     low(interval, newLow);
@@ -271,8 +309,8 @@
   template <typename interval_type>
   typename enable_if<typename gtl_and<y_i_deconvolve, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type &
   deconvolve(interval_type& interval,
-             typename interval_traits<interval_type>::coordinate_type b) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+             typename interval_coordinate_type<interval_type>::type b) {
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit newLow  = low(interval)  - b;
     Unit newHigh = high(interval) - b;
     low(interval, newLow);
@@ -291,7 +329,7 @@
     interval_type>::type &
   convolve(interval_type& interval,
            const interval_type_2& b) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit newLow  = low(interval)  + low(b);
     Unit newHigh = high(interval) + high(b);
     low(interval, newLow);
@@ -310,7 +348,7 @@
     interval_type>::type &
   deconvolve(interval_type& interval,
              const interval_type_2& b) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit newLow  = low(interval)  - low(b);
     Unit newHigh = high(interval) - high(b);
     low(interval, newLow);
@@ -329,7 +367,7 @@
     interval_type>::type &
   reflected_convolve(interval_type& interval,
                      const interval_type_2& b) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit newLow  = low(interval)  - high(b);
     Unit newHigh = high(interval) - low(b);
     low(interval, newLow);
@@ -348,7 +386,7 @@
     interval_type>::type &
   reflected_deconvolve(interval_type& interval,
                        const interval_type_2& b) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit newLow  = low(interval)  + high(b);
     Unit newHigh = high(interval) + low(b);
     low(interval, newLow);
@@ -363,8 +401,8 @@
   typename enable_if< typename gtl_and<y_i_e_dist1, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
                        typename interval_difference_type<interval_type>::type>::type
   euclidean_distance(const interval_type& interval,
-                     typename interval_traits<interval_type>::coordinate_type position) {
-    typedef typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::coordinate_difference Unit;
+                     typename interval_coordinate_type<interval_type>::type position) {
+    typedef typename coordinate_traits<typename interval_difference_type<interval_type>::type>::coordinate_difference Unit;
     Unit dist[3] = {0, (Unit)low(interval) - (Unit)position, (Unit)position - (Unit)high(interval)};
     return dist[ (dist[1] > 0) + ((dist[2] > 0) << 1) ];
   }
@@ -379,7 +417,7 @@
     typename interval_difference_type<interval_type>::type>::type
   euclidean_distance(const interval_type& interval,
                      const interval_type_2& b) {
-    typedef typename coordinate_traits<typename interval_traits<interval_type>::coordinate_type>::coordinate_difference Unit;
+    typedef typename coordinate_traits<typename interval_difference_type<interval_type>::type>::coordinate_difference Unit;
     Unit dist[3] = {0, (Unit)low(interval) - (Unit)high(b), (Unit)low(b) - (Unit)high(interval)};
     return dist[ (dist[1] > 0) + ((dist[2] > 0) << 1) ];
   }
@@ -446,7 +484,7 @@
                                          typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
                        bool>::type 
   intersect(interval_type& interval, const interval_type_2& b, bool consider_touch = true) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit lowVal = (std::max)(low(interval), low(b));
     Unit highVal = (std::min)(high(interval), high(b));
     bool valid = consider_touch ?
@@ -468,7 +506,7 @@
                       typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
     interval_type>::type &
   generalized_intersect(interval_type& interval, const interval_type_2& b) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit coords[4] = {low(interval), high(interval), low(b), high(b)};
     //consider implementing faster sorting of small fixed length range
     polygon_sort(coords, coords+4);
@@ -483,7 +521,7 @@
   template <typename interval_type>
   typename enable_if< typename gtl_and<y_i_bloat, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
                        interval_type>::type &
-  bloat(interval_type& interval, typename interval_traits<interval_type>::coordinate_type bloating) {
+  bloat(interval_type& interval, typename interval_coordinate_type<interval_type>::type bloating) {
     low(interval, low(interval)-bloating);
     high(interval, high(interval)+bloating);
     return interval;
@@ -495,7 +533,7 @@
   template <typename interval_type>
   typename enable_if< typename gtl_and<y_i_bloat2, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
                        interval_type>::type &
-  bloat(interval_type& interval, direction_1d dir, typename interval_traits<interval_type>::coordinate_type bloating) {
+  bloat(interval_type& interval, direction_1d dir, typename interval_coordinate_type<interval_type>::type bloating) {
     set(interval, dir, get(interval, dir) + dir.get_sign() * bloating);
     return interval;
   }
@@ -506,7 +544,7 @@
   template <typename interval_type>
   typename enable_if< typename gtl_and<y_i_shrink, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
                        interval_type>::type &
-  shrink(interval_type& interval, typename interval_traits<interval_type>::coordinate_type shrinking) {
+  shrink(interval_type& interval, typename interval_coordinate_type<interval_type>::type shrinking) {
     return bloat(interval, -shrinking);
   }
 
@@ -516,31 +554,33 @@
   template <typename interval_type>
   typename enable_if< typename gtl_and<y_i_shrink2, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
                        interval_type>::type &
-  shrink(interval_type& interval, direction_1d dir, typename interval_traits<interval_type>::coordinate_type shrinking) {
+  shrink(interval_type& interval, direction_1d dir, typename interval_coordinate_type<interval_type>::type shrinking) {
     return bloat(interval, dir, -shrinking);
   }
 
+  struct y_i_encompass : gtl_yes {};
+
   // Enlarge `this` Interval to encompass the specified Interval
   template <typename interval_type, typename interval_type_2>
-  bool
-  encompass(interval_type& interval, const interval_type_2& b,
-  typename enable_if<
-    typename gtl_and< typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
-            typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and_3<
+        y_i_encompass,
+        typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type,
+        typename is_interval_concept<typename geometry_concept<interval_type_2>::type>::type>::type,
+      bool>::type
+  encompass(interval_type& interval, const interval_type_2& b) {
     bool retval = !contains(interval, b, true);
     low(interval, (std::min)(low(interval), low(b)));
     high(interval, (std::max)(high(interval), high(b)));
     return retval;
   }    
 
-  struct y_i_encompass : gtl_yes {};
+  struct y_i_encompass2 : gtl_yes {};
 
   // Enlarge `this` Interval to encompass the specified Interval
   template <typename interval_type>
-  typename enable_if< typename gtl_and<y_i_encompass, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
+  typename enable_if< typename gtl_and<y_i_encompass2, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
                        bool>::type
-  encompass(interval_type& interval, typename interval_traits<interval_type>::coordinate_type b) {
+  encompass(interval_type& interval, typename interval_coordinate_type<interval_type>::type b) {
     bool retval = !contains(interval, b, true);
     low(interval, (std::min)(low(interval), b));
     high(interval, (std::max)(high(interval), b));
@@ -553,7 +593,7 @@
   template <typename interval_type>
   typename enable_if<typename gtl_and<y_i_get_half, typename is_mutable_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, interval_type>::type 
   get_half(const interval_type& interval, direction_1d d1d) {
-    typedef typename interval_traits<interval_type>::coordinate_type Unit;
+    typedef typename interval_coordinate_type<interval_type>::type Unit;
     Unit c = (get(interval, LOW) + get(interval, HIGH)) / 2;
     return construct<interval_type>((d1d == LOW) ? get(interval, LOW) : c,
                                     (d1d == LOW) ? c : get(interval, HIGH));
Modified: trunk/boost/polygon/point_3d_concept.hpp
==============================================================================
--- trunk/boost/polygon/point_3d_concept.hpp	(original)
+++ trunk/boost/polygon/point_3d_concept.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -39,7 +39,7 @@
   struct point_3d_difference_type_by_concept { typedef void type; };
   template <typename T>
   struct point_3d_difference_type_by_concept<T, gtl_yes> { 
-    typedef typename coordinate_traits<typename point_3d_traits<T>::coordinate_type>::coordinate_difference type; };
+    typedef typename coordinate_traits<typename point_3d_coordinate_type<T>::type>::coordinate_difference type; };
 
   template <typename T>
   struct point_3d_difference_type {
@@ -51,7 +51,7 @@
   struct point_3d_distance_type_by_concept { typedef void type; };
   template <typename T>
   struct point_3d_distance_type_by_concept<T, gtl_yes> { 
-    typedef typename coordinate_traits<typename point_3d_traits<T>::coordinate_type>::coordinate_distance type; };
+    typedef typename coordinate_traits<typename point_3d_coordinate_type<T>::type>::coordinate_distance type; };
 
   template <typename T>
   struct point_3d_distance_type {
@@ -62,7 +62,7 @@
   struct y_p3d_get : gtl_yes {};
 
   template <typename T>
-  typename enable_if< typename gtl_and<y_p3d_get, typename gtl_if<typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type>::type, 
+  typename enable_if< typename gtl_and<y_p3d_get, typename is_point_3d_concept<typename geometry_concept<T>::type>::type>::type,
                        typename point_3d_coordinate_type<T>::type >::type 
   get(const T& point, orientation_3d orient) { return point_3d_traits<T>::get(point, orient); }
   
@@ -103,7 +103,7 @@
 
   template <typename point_type>
   typename enable_if< typename gtl_and<y_p3d_z, typename is_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, 
-                       typename point_3d_traits<point_type>::coordinate_type >::type 
+                       typename point_3d_coordinate_type<point_type>::type >::type 
   z(const point_type& point) { return get(point, PROXIMAL); }
 
   struct y_p3d_x : gtl_yes {};
@@ -142,7 +142,7 @@
                                           typename is_point_3d_concept<typename geometry_concept<point_type_2>::type>::type>::type, 
                        typename point_3d_difference_type<point_type_1>::type>::type
   euclidean_distance(const point_type_1& point1, const point_type_2& point2, orientation_3d orient) {
-    typedef typename coordinate_traits<typename point_3d_traits<point_type_1>::coordinate_type>::coordinate_difference return_type;
+    typedef typename coordinate_traits<typename point_3d_coordinate_type<point_type_1>::type>::coordinate_difference return_type;
     return_type return_value =
       (return_type)get(point1, orient) - (return_type)get(point2, orient);
     return return_value < 0 ? -return_value : return_value;
@@ -167,7 +167,7 @@
     typename gtl_same_type<point_3d_concept, typename geometry_concept<point_type_2>::type>::type>::type,
                        typename point_3d_distance_type<point_type_1>::type>::type
   euclidean_distance(const point_type_1& point1, const point_type_2& point2) {
-    typedef typename coordinate_traits<typename point_3d_traits<point_type_1>::coordinate_type>::coordinate_distance return_value;
+    typedef typename coordinate_traits<typename point_3d_coordinate_type<point_type_1>::type>::coordinate_distance return_value;
     return_value pdist = (return_value)euclidean_distance(point1, point2, PROXIMAL);
     pdist *= pdist;
     return sqrt((double)(distance_squared(point1, point2) + pdist));
@@ -207,10 +207,10 @@
   typename enable_if< typename gtl_and<y_p3d_scale_up, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, 
                        point_type>::type &
   scale_up(point_type& point, 
-           typename coordinate_traits<typename point_3d_traits<point_type>::coordinate_type>::unsigned_area_type factor) {
-    x(point, x(point) * (typename point_3d_traits<point_type>::coordinate_type)factor);
-    y(point, y(point) * (typename point_3d_traits<point_type>::coordinate_type)factor);
-    z(point, z(point) * (typename point_3d_traits<point_type>::coordinate_type)factor);
+           typename coordinate_traits<typename point_3d_coordinate_type<point_type>::type>::unsigned_area_type factor) {
+    x(point, x(point) * (typename point_3d_coordinate_type<point_type>::type)factor);
+    y(point, y(point) * (typename point_3d_coordinate_type<point_type>::type)factor);
+    z(point, z(point) * (typename point_3d_coordinate_type<point_type>::type)factor);
     return point;
   }
 
@@ -220,8 +220,8 @@
   typename enable_if< typename gtl_and<y_p3d_scale_down, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, 
                        point_type>::type &
   scale_down(point_type& point, 
-             typename coordinate_traits<typename point_3d_traits<point_type>::coordinate_type>::unsigned_area_type factor) {
-    typedef typename point_3d_traits<point_type>::coordinate_type Unit;
+             typename coordinate_traits<typename point_3d_coordinate_type<point_type>::type>::unsigned_area_type factor) {
+    typedef typename point_3d_coordinate_type<point_type>::type Unit;
     typedef typename coordinate_traits<Unit>::coordinate_distance dt;
     x(point, scaling_policy<Unit>::round((dt)(x(point)) / (dt)factor)); 
     y(point, scaling_policy<Unit>::round((dt)(y(point)) / (dt)factor)); 
@@ -236,7 +236,7 @@
                        point_type>::type &
   scale(point_type& point, 
         const scaling_type& scaling) {
-    typedef typename point_3d_traits<point_type>::coordinate_type Unit;
+    typedef typename point_3d_coordinate_type<point_type>::type Unit;
     Unit x_(x(point)), y_(y(point)), z_(z(point));
     scaling.scale(x_, y_, z_);
     x(point, x_);
@@ -251,7 +251,7 @@
   typename enable_if< typename gtl_and<y_p3d_transform, typename is_mutable_point_3d_concept<typename geometry_concept<point_type>::type>::type>::type, 
                        point_type>::type &
   transform(point_type& point, const transformation_type& transformation) {
-    typedef typename point_3d_traits<point_type>::coordinate_type Unit;
+    typedef typename point_3d_coordinate_type<point_type>::type Unit;
     Unit x_(x(point)), y_(y(point)), z_(z(point));
     transformation.transform(x_, y_, z_);
     x(point, x_);
Modified: trunk/boost/polygon/point_concept.hpp
==============================================================================
--- trunk/boost/polygon/point_concept.hpp	(original)
+++ trunk/boost/polygon/point_concept.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -42,7 +42,7 @@
   struct point_difference_type_by_concept { typedef void type; };
   template <typename T>
   struct point_difference_type_by_concept<T, gtl_yes> { 
-    typedef typename coordinate_traits<typename point_traits<T>::coordinate_type>::coordinate_difference type; };
+    typedef typename coordinate_traits<typename point_coordinate_type<T>::type>::coordinate_difference type; };
 
   template <typename T>
   struct point_difference_type {
@@ -54,7 +54,7 @@
   struct point_distance_type_by_concept { typedef void type; };
   template <typename T>
   struct point_distance_type_by_concept<T, gtl_yes> { 
-    typedef typename coordinate_traits<typename point_traits<T>::coordinate_type>::coordinate_distance type; };
+    typedef typename coordinate_traits<typename point_coordinate_type<T>::type>::coordinate_distance type; };
 
   template <typename T>
   struct point_distance_type {
@@ -62,36 +62,42 @@
             T, typename is_point_concept<typename geometry_concept<T>::type>::type>::type type;
   };
 
+  struct y_pt_get : gtl_yes {};
+
   template <typename T>
-  typename point_coordinate_type<T>::type 
-  get(const T& point, orientation_2d orient,
-  typename enable_if< typename gtl_if<typename is_point_concept<typename geometry_concept<T>::type>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and<y_pt_get, typename is_point_concept<typename geometry_concept<T>::type>::type>::type, 
+                      typename point_coordinate_type<T>::type >::type
+  get(const T& point, orientation_2d orient) {
     return point_traits<T>::get(point, orient);
   }
-  
+
+  struct y_pt_set : gtl_yes {};
+
   template <typename T, typename coordinate_type>
-  void 
-  set(T& point, orientation_2d orient, coordinate_type value,
-  typename enable_if<typename is_mutable_point_concept<typename geometry_concept<T>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and<y_pt_set, typename is_mutable_point_concept<typename geometry_concept<T>::type>::type>::type, 
+                      void>::type
+  set(T& point, orientation_2d orient, coordinate_type value) {
     point_mutable_traits<T>::set(point, orient, value);
   }
-  
+
+  struct y_pt_construct : gtl_yes {};
+
   template <typename T, typename coordinate_type1, typename coordinate_type2>
-  T
-  construct(coordinate_type1 x_value, coordinate_type2 y_value,
-  typename enable_if<typename is_mutable_point_concept<typename geometry_concept<T>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and<y_pt_construct, typename is_mutable_point_concept<typename geometry_concept<T>::type>::type>::type, 
+                      T>::type
+  construct(coordinate_type1 x_value, coordinate_type2 y_value) {
     return point_mutable_traits<T>::construct(x_value, y_value); 
   }
 
+  struct y_pt_assign : gtl_yes {};
+
   template <typename T1, typename T2>
-  T1&
-  assign(T1& lvalue, const T2& rvalue,
-  typename enable_if< typename gtl_and< typename is_mutable_point_concept<typename geometry_concept<T1>::type>::type,
-                                         typename is_point_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
-  ) {
+  typename enable_if<typename gtl_and_3<
+        y_pt_assign,
+        typename is_mutable_point_concept<typename geometry_concept<T1>::type>::type, 
+        typename is_point_concept<typename geometry_concept<T2>::type>::type>::type, 
+      T1>::type &
+  assign(T1& lvalue, const T2& rvalue) {
     set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL));
     set(lvalue, VERTICAL, get(rvalue, VERTICAL));
     return lvalue;
@@ -101,7 +107,7 @@
 
   template <typename point_type>
   typename enable_if< typename gtl_and<y_p_x, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, 
-                       typename point_traits<point_type>::coordinate_type >::type 
+                      typename point_coordinate_type<point_type>::type >::type 
   x(const point_type& point) {
     return get(point, HORIZONTAL);
   }
@@ -110,7 +116,7 @@
 
   template <typename point_type>
   typename enable_if< typename gtl_and<y_p_y, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, 
-                       typename point_traits<point_type>::coordinate_type >::type 
+                      typename point_coordinate_type<point_type>::type >::type 
   y(const point_type& point) {
     return get(point, VERTICAL);
   }
@@ -133,57 +139,66 @@
     set(point, VERTICAL, value);
   }
 
+  struct y_pt_equiv : gtl_yes {};
+
   template <typename T, typename T2>
-  bool
-  equivalence(const T& point1, const T2& point2,
-    typename enable_if< typename gtl_and<typename gtl_same_type<point_concept, typename geometry_concept<T>::type>::type,
-              typename is_point_concept<typename geometry_concept<T2>::type>::type>::type>::type * = 0
-  ) {
-    typename point_traits<T>::coordinate_type x1 = x(point1);
-    typename point_traits<T2>::coordinate_type x2 = get(point2, HORIZONTAL);
-    typename point_traits<T>::coordinate_type y1 = get(point1, VERTICAL);
-    typename point_traits<T2>::coordinate_type y2 = y(point2);
+  typename enable_if<typename gtl_and_3<y_pt_equiv,
+        typename gtl_same_type<point_concept, typename geometry_concept<T>::type>::type, 
+        typename is_point_concept<typename geometry_concept<T2>::type>::type>::type,
+      bool>::type
+  equivalence(const T& point1, const T2& point2) {
+    typename point_coordinate_type<T>::type x1 = x(point1);
+    typename point_coordinate_type<T2>::type x2 = get(point2, HORIZONTAL);
+    typename point_coordinate_type<T>::type y1 = get(point1, VERTICAL);
+    typename point_coordinate_type<T2>::type y2 = y(point2);
     return x1 == x2 && y1 == y2;
   }
 
+  struct y_pt_man_dist : gtl_yes {};
+
   template <typename point_type_1, typename point_type_2>
-  typename point_difference_type<point_type_1>::type
-  manhattan_distance(const point_type_1& point1, const point_type_2& point2,
-  typename enable_if< typename gtl_and<typename gtl_same_type<point_concept, typename geometry_concept<point_type_1>::type>::type, 
-  typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0) {
+  typename enable_if< typename gtl_and_3<
+        y_pt_man_dist,
+        typename gtl_same_type<point_concept, typename geometry_concept<point_type_1>::type>::type, 
+        typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type,
+      typename point_difference_type<point_type_1>::type>::type
+  manhattan_distance(const point_type_1& point1, const point_type_2& point2) {
     return euclidean_distance(point1, point2, HORIZONTAL) + euclidean_distance(point1, point2, VERTICAL);
   }
   
-  struct y_i_ed1 : gtl_yes {};
+  struct y_pt_ed1 : gtl_yes {};
 
   template <typename point_type_1, typename point_type_2>
-  typename enable_if< typename gtl_and_3<y_i_ed1, typename is_point_concept<typename geometry_concept<point_type_1>::type>::type, 
+  typename enable_if< typename gtl_and_3<y_pt_ed1, typename is_point_concept<typename geometry_concept<point_type_1>::type>::type, 
   typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type,
   typename point_difference_type<point_type_1>::type>::type
   euclidean_distance(const point_type_1& point1, const point_type_2& point2, orientation_2d orient) {
-    typename coordinate_traits<typename point_traits<point_type_1>::coordinate_type>::coordinate_difference return_value =
+    typename coordinate_traits<typename point_coordinate_type<point_type_1>::type>::coordinate_difference return_value =
       get(point1, orient) - get(point2, orient);
-    return return_value < 0 ? (typename coordinate_traits<typename point_traits<point_type_1>::coordinate_type>::coordinate_difference)-return_value : return_value;
+    return return_value < 0 ? (typename coordinate_traits<typename point_coordinate_type<point_type_1>::type>::coordinate_difference)-return_value : return_value;
   }
   
-  struct y_i_ed2 : gtl_yes {};
+  struct y_pt_ed2 : gtl_yes {};
 
   template <typename point_type_1, typename point_type_2>
-  typename enable_if< typename gtl_and_3<y_i_ed2, typename gtl_same_type<point_concept, typename geometry_concept<point_type_1>::type>::type,
+  typename enable_if< typename gtl_and_3<y_pt_ed2, typename gtl_same_type<point_concept, typename geometry_concept<point_type_1>::type>::type,
   typename gtl_same_type<point_concept, typename geometry_concept<point_type_2>::type>::type>::type,
   typename point_distance_type<point_type_1>::type>::type
   euclidean_distance(const point_type_1& point1, const point_type_2& point2) {
-    typedef typename point_traits<point_type_1>::coordinate_type Unit;
+    typedef typename point_coordinate_type<point_type_1>::type Unit;
     return sqrt((double)(distance_squared(point1, point2)));
   }
+
+  struct y_pt_eds : gtl_yes {};
   
   template <typename point_type_1, typename point_type_2>
-  typename point_difference_type<point_type_1>::type
-  distance_squared(const point_type_1& point1, const point_type_2& point2,
-    typename enable_if< typename gtl_and<typename is_point_concept<typename geometry_concept<point_type_1>::type>::type,
-                   typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0
-  ) {
-    typedef typename point_traits<point_type_1>::coordinate_type Unit;
+  typename enable_if< typename gtl_and_3<
+        y_pt_eds,
+        typename is_point_concept<typename geometry_concept<point_type_1>::type>::type,
+        typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type,
+      typename point_difference_type<point_type_1>::type>::type
+  distance_squared(const point_type_1& point1, const point_type_2& point2) {
+    typedef typename point_coordinate_type<point_type_1>::type Unit;
     typename coordinate_traits<Unit>::coordinate_difference dx = euclidean_distance(point1, point2, HORIZONTAL);
     typename coordinate_traits<Unit>::coordinate_difference dy = euclidean_distance(point1, point2, VERTICAL);
     dx *= dx;
@@ -191,58 +206,66 @@
     return dx + dy;
   }
 
+  struct y_pt_convolve : gtl_yes {};
+
   template <typename point_type_1, typename point_type_2>
-  point_type_1 &
-  convolve(point_type_1& lvalue, const point_type_2& rvalue,
-  typename enable_if< typename gtl_and<typename is_mutable_point_concept<typename geometry_concept<point_type_1>::type>::type, 
-  typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and_3<
+        y_pt_convolve,
+        typename is_mutable_point_concept<typename geometry_concept<point_type_1>::type>::type, 
+        typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type,
+      point_type_1>::type &
+  convolve(point_type_1& lvalue, const point_type_2& rvalue) {
     x(lvalue, x(lvalue) + x(rvalue));
     y(lvalue, y(lvalue) + y(rvalue));
     return lvalue;
   }
-  
+
+  struct y_pt_deconvolve : gtl_yes {};
+
   template <typename point_type_1, typename point_type_2>
-  point_type_1 &
-  deconvolve(point_type_1& lvalue, const point_type_2& rvalue,
-  typename enable_if< typename gtl_and<typename is_mutable_point_concept<typename geometry_concept<point_type_1>::type>::type, 
-  typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and_3<
+        y_pt_deconvolve,
+        typename is_mutable_point_concept<typename geometry_concept<point_type_1>::type>::type, 
+        typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type,
+      point_type_1>::type &
+  deconvolve(point_type_1& lvalue, const point_type_2& rvalue) {
     x(lvalue, x(lvalue) - x(rvalue));
     y(lvalue, y(lvalue) - y(rvalue));
     return lvalue;
   }
+
+  struct y_pt_scale_up : gtl_yes {};
   
   template <typename point_type, typename coord_type>
-  point_type &
-  scale_up(point_type& point, coord_type factor,
-  typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
-  ) {
-    typedef typename point_traits<point_type>::coordinate_type Unit;
+  typename enable_if< typename gtl_and<y_pt_scale_up, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type, 
+                      point_type>::type &
+  scale_up(point_type& point, coord_type factor) {
+    typedef typename point_coordinate_type<point_type>::type Unit;
     x(point, x(point) * (Unit)factor);
     y(point, y(point) * (Unit)factor);
     return point;
   }
 
+  struct y_pt_scale_down : gtl_yes {};
+
   template <typename point_type, typename coord_type>
-  point_type &
-  scale_down(point_type& point, coord_type factor,
-  typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
-  ) {
-    typedef typename point_traits<point_type>::coordinate_type Unit;
+  typename enable_if< typename gtl_and<y_pt_scale_down, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type, 
+                      point_type>::type &
+  scale_down(point_type& point, coord_type factor) {
+    typedef typename point_coordinate_type<point_type>::type Unit;
     typedef typename coordinate_traits<Unit>::coordinate_distance dt;
     x(point, scaling_policy<Unit>::round((dt)((dt)(x(point)) / (dt)factor))); 
     y(point, scaling_policy<Unit>::round((dt)((dt)(y(point)) / (dt)factor))); 
     return point;
   }
 
+  struct y_pt_scale : gtl_yes {};
+
   template <typename point_type, typename scaling_type>
-  point_type &
-  scale(point_type& point, 
-        const scaling_type& scaling,
-        typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
-        ) {
-    typedef typename point_traits<point_type>::coordinate_type Unit;
+  typename enable_if< typename gtl_and<y_pt_scale, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type, 
+                      point_type>::type &
+  scale(point_type& point, const scaling_type& scaling) {
+    typedef typename point_coordinate_type<point_type>::type Unit;
     Unit x_(x(point)), y_(y(point));
     scaling.scale(x_, y_);
     x(point, x_);
@@ -250,12 +273,13 @@
     return point;
   }
 
+  struct y_pt_transform : gtl_yes {};
+
   template <typename point_type, typename transformation_type>
-  point_type &
-  transform(point_type& point, const transformation_type& transformation,
-  typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
-  ) {
-    typedef typename point_traits<point_type>::coordinate_type Unit;
+  typename enable_if< typename gtl_and<y_pt_transform, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type, 
+                      point_type>::type &
+  transform(point_type& point, const transformation_type& transformation) {
+    typedef typename point_coordinate_type<point_type>::type Unit;
     Unit x_(x(point)), y_(y(point));
     transformation.transform(x_, y_);
     x(point, x_);
@@ -266,16 +290,11 @@
   struct y_pt_move : gtl_yes {};
 
   template <typename point_type>
-  typename enable_if< 
-    typename gtl_and< y_pt_move, 
-                      typename is_mutable_point_concept<
-      typename geometry_concept<point_type>::type>::type>::type, 
-    point_type>::type &
+  typename enable_if< typename gtl_and<y_pt_move, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type, 
+                      point_type>::type &
   move(point_type& point, orientation_2d orient,
-       typename point_traits<point_type>::coordinate_type displacement,
-       typename enable_if<typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type>::type * = 0
-       ) {
-    typedef typename point_traits<point_type>::coordinate_type Unit;
+       typename point_coordinate_type<point_type>::type displacement) {
+    typedef typename point_coordinate_type<point_type>::type Unit;
     Unit v(get(point, orient));
     set(point, orient, v + displacement);
     return point;
Modified: trunk/boost/polygon/polygon.hpp
==============================================================================
--- trunk/boost/polygon/polygon.hpp	(original)
+++ trunk/boost/polygon/polygon.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -88,8 +88,9 @@
 
 #include "polygon_set_concept.hpp"
 
-#include "directed_line_segment_data.hpp"
-#include "directed_line_segment_traits.hpp"
-#include "directed_line_segment_concept.hpp"
+//segment
+#include "segment_data.hpp"
+#include "segment_traits.hpp"
+#include "segment_concept.hpp"
 
 #endif
Modified: trunk/boost/polygon/polygon_90_set_concept.hpp
==============================================================================
--- trunk/boost/polygon/polygon_90_set_concept.hpp	(original)
+++ trunk/boost/polygon/polygon_90_set_concept.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -460,24 +460,27 @@
     return polygon_set;
   }
 
+  struct y_p_s_move : gtl_yes {};
+
   //move
   template <typename polygon_set_type>
-  polygon_set_type&
+  typename enable_if< typename gtl_and<y_p_s_move, typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type>::type,
+                      polygon_set_type>::type &
   move(polygon_set_type& polygon_set,
-  orientation_2d orient, typename polygon_90_set_traits<polygon_set_type>::coordinate_type displacement,
-       typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type * = 0) {
+  orientation_2d orient, typename polygon_90_set_traits<polygon_set_type>::coordinate_type displacement) {
     if(orient == HORIZONTAL)
       return move(polygon_set, displacement, 0);
     else 
       return move(polygon_set, 0, displacement);
   }
 
+  struct y_p_s_move2 : gtl_yes {};
+
   template <typename polygon_set_type>
-  polygon_set_type&
+  typename enable_if< typename gtl_and<y_p_s_move2, typename gtl_if<typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type>::type,
+                      polygon_set_type>::type &
   move(polygon_set_type& polygon_set, typename polygon_90_set_traits<polygon_set_type>::coordinate_type x_displacement, 
-  typename polygon_90_set_traits<polygon_set_type>::coordinate_type y_displacement,
-  typename enable_if< typename is_mutable_polygon_90_set_type<polygon_set_type>::type>::type * = 0
-  ) {
+  typename polygon_90_set_traits<polygon_set_type>::coordinate_type y_displacement) {
     typedef typename polygon_90_set_traits<polygon_set_type>::coordinate_type Unit;
     polygon_90_set_data<Unit> ps;
     assign(ps, polygon_set);
Modified: trunk/boost/polygon/polygon_traits.hpp
==============================================================================
--- trunk/boost/polygon/polygon_traits.hpp	(original)
+++ trunk/boost/polygon/polygon_traits.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -756,8 +756,6 @@
   void snap_point_vector_to_45(std::vector<point_data<Unit> >& pts) {
     typedef point_data<Unit> Point;
     if(pts.size() < 3) { pts.clear(); return; }
-    Point firstPt = pts.front();
-    Point prevPt = firstPt;
     typename std::vector<point_data<Unit> >::iterator endLocation = std::unique(pts.begin(), pts.end());
     if(endLocation != pts.end()){
       pts.resize(endLocation - pts.begin());
Modified: trunk/boost/polygon/rectangle_concept.hpp
==============================================================================
--- trunk/boost/polygon/rectangle_concept.hpp	(original)
+++ trunk/boost/polygon/rectangle_concept.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -63,7 +63,7 @@
   struct rectangle_difference_type_by_concept { typedef void type; };
   template <typename T>
   struct rectangle_difference_type_by_concept<T, gtl_yes> { 
-    typedef typename coordinate_traits<typename rectangle_traits<T>::coordinate_type>::coordinate_difference type; };
+     typedef typename coordinate_traits<typename rectangle_traits<T>::coordinate_type>::coordinate_difference type; };
 
   template <typename T>
   struct rectangle_difference_type {
@@ -75,7 +75,7 @@
   struct rectangle_distance_type_by_concept { typedef void type; };
   template <typename T>
   struct rectangle_distance_type_by_concept<T, gtl_yes> { 
-    typedef typename coordinate_traits<typename rectangle_traits<T>::coordinate_type>::coordinate_distance type; };
+    typedef typename coordinate_traits<typename rectangle_coordinate_type<T>::type>::coordinate_distance type; };
 
   template <typename T>
   struct rectangle_distance_type {
@@ -83,19 +83,20 @@
       T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type;
   };
 
+  struct y_r_get_interval : gtl_yes {};
+
   template <typename T>
-  typename rectangle_interval_type<T>::type 
-  get(const T& rectangle, orientation_2d orient,
-  typename enable_if< typename gtl_if<typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type>::type * = 0
-  ) {
-    return rectangle_traits<T>::get(rectangle, orient); 
+  typename enable_if< typename gtl_and<y_r_get_interval, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
+                      typename rectangle_interval_type<T>::type>::type
+  get(const T& rectangle, orientation_2d orient) {
+    return rectangle_traits<T>::get(rectangle, orient);
   }
 
   struct y_r_h : gtl_yes {};
 
   template <typename T>
-  typename enable_if< typename gtl_and<y_r_h, typename gtl_if<typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type>::type,
-                       typename rectangle_traits<T>::interval_type>::type
+  typename enable_if< typename gtl_and<y_r_h, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
+                       typename rectangle_interval_type<T>::type>::type
   horizontal(const T& rectangle) {
     return rectangle_traits<T>::get(rectangle, HORIZONTAL); 
   }
@@ -103,8 +104,8 @@
   struct y_r_v : gtl_yes {};
 
   template <typename T>
-  typename enable_if< typename gtl_and<y_r_v, typename gtl_if<typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type>::type,
-                       typename rectangle_traits<T>::interval_type>::type
+  typename enable_if< typename gtl_and<y_r_v, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
+                       typename rectangle_interval_type<T>::type>::type
   vertical(const T& rectangle) {
     return rectangle_traits<T>::get(rectangle, VERTICAL); 
   }
@@ -210,7 +211,7 @@
   struct y_r_get : gtl_yes {};
 
   template <typename rectangle_type>
-  typename enable_if< typename gtl_and<y_r_get, typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
+  typename enable_if< typename gtl_and<y_r_get, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
                        typename rectangle_coordinate_type<rectangle_type>::type>::type
   get(const rectangle_type& rectangle, orientation_2d orient, direction_1d dir) {
     return get(rectangle_traits<rectangle_type>::get(rectangle, orient), dir); 
@@ -221,8 +222,8 @@
   template <typename rectangle_type>
   typename enable_if<typename gtl_and<y_r_set3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type 
   set(rectangle_type& rectangle, orientation_2d orient, direction_1d dir, 
-      typename rectangle_traits<rectangle_type>::coordinate_type value) {
-    typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orient);
+      typename rectangle_coordinate_type<rectangle_type>::type value) {
+    typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
     set(ivl, dir, value);
     set(rectangle, orient, ivl);
   }
@@ -230,7 +231,7 @@
   struct y_r_xl : gtl_yes {};
 
   template <typename rectangle_type>
-  typename enable_if< typename gtl_and<y_r_xl, typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
+  typename enable_if< typename gtl_and<y_r_xl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
                        typename rectangle_coordinate_type<rectangle_type>::type>::type
   xl(const rectangle_type& rectangle) {
     return get(rectangle, HORIZONTAL, LOW);
@@ -240,14 +241,14 @@
 
   template <typename rectangle_type>
   typename enable_if<typename gtl_and<y_r_xl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type 
-  xl(rectangle_type& rectangle, typename rectangle_traits<rectangle_type>::coordinate_type value) {
+      xl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
     return set(rectangle, HORIZONTAL, LOW, value);
   }
 
   struct y_r_xh : gtl_yes {};
 
   template <typename rectangle_type>
-  typename enable_if< typename gtl_and<y_r_xh, typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
+  typename enable_if< typename gtl_and<y_r_xh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
                        typename rectangle_coordinate_type<rectangle_type>::type>::type
   xh(const rectangle_type& rectangle) {
     return get(rectangle, HORIZONTAL, HIGH);
@@ -257,14 +258,14 @@
 
   template <typename rectangle_type>
   typename enable_if<typename gtl_and<y_r_xh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type 
-  xh(rectangle_type& rectangle, typename rectangle_traits<rectangle_type>::coordinate_type value) {
+  xh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
     return set(rectangle, HORIZONTAL, HIGH, value);
   }
 
   struct y_r_yl : gtl_yes {};
 
   template <typename rectangle_type>
-  typename enable_if< typename gtl_and<y_r_yl, typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
+  typename enable_if< typename gtl_and<y_r_yl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
                        typename rectangle_coordinate_type<rectangle_type>::type>::type
   yl(const rectangle_type& rectangle) {
     return get(rectangle, VERTICAL, LOW);
@@ -274,14 +275,14 @@
 
   template <typename rectangle_type>
   typename enable_if<typename gtl_and<y_r_yl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type 
-  yl(rectangle_type& rectangle, typename rectangle_traits<rectangle_type>::coordinate_type value) {
+      yl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
     return set(rectangle, VERTICAL, LOW, value);
   }
 
   struct y_r_yh : gtl_yes {};
 
   template <typename rectangle_type>
-  typename enable_if< typename gtl_and<y_r_yh, typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
+  typename enable_if< typename gtl_and<y_r_yh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
                        typename rectangle_coordinate_type<rectangle_type>::type>::type
   yh(const rectangle_type& rectangle) {
     return get(rectangle, VERTICAL, HIGH);
@@ -291,44 +292,44 @@
 
   template <typename rectangle_type>
   typename enable_if<typename gtl_and<y_r_yh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type 
-  yh(rectangle_type& rectangle, typename rectangle_traits<rectangle_type>::coordinate_type value) {
+      yh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
     return set(rectangle, VERTICAL, HIGH, value);
   }
 
   struct y_r_ll : gtl_yes {};
 
   template <typename rectangle_type>
-  typename enable_if<typename gtl_and<y_r_ll,  typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
-                       point_data<typename rectangle_traits<rectangle_type>::coordinate_type> >::type
+  typename enable_if<typename gtl_and<y_r_ll,  typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
+                       point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
   ll(const rectangle_type& rectangle) {
-    return point_data<typename rectangle_traits<rectangle_type>::coordinate_type> (xl(rectangle), yl(rectangle));
+    return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yl(rectangle));
   }
 
   struct y_r_lr : gtl_yes {};
 
   template <typename rectangle_type>
-  typename enable_if<typename gtl_and<y_r_lr,  typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
-                       point_data<typename rectangle_traits<rectangle_type>::coordinate_type> >::type
+  typename enable_if<typename gtl_and<y_r_lr,  typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
+                       point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
   lr(const rectangle_type& rectangle) {
-    return point_data<typename rectangle_traits<rectangle_type>::coordinate_type> (xh(rectangle), yl(rectangle));
+    return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yl(rectangle));
   }
 
   struct y_r_ul : gtl_yes {};
 
   template <typename rectangle_type>
-  typename enable_if<typename gtl_and<y_r_ul,  typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
-                       point_data<typename rectangle_traits<rectangle_type>::coordinate_type> >::type
+  typename enable_if<typename gtl_and<y_r_ul,  typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
+                       point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
   ul(const rectangle_type& rectangle) {
-    return point_data<typename rectangle_traits<rectangle_type>::coordinate_type> (xl(rectangle), yh(rectangle));
+    return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yh(rectangle));
   }
 
   struct y_r_ur : gtl_yes {};
 
   template <typename rectangle_type>
-  typename enable_if<typename gtl_and<y_r_ur,  typename gtl_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
-                       point_data<typename rectangle_traits<rectangle_type>::coordinate_type> >::type
+  typename enable_if<typename gtl_and<y_r_ur,  typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
+                       point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
   ur(const rectangle_type& rectangle) {
-    return point_data<typename rectangle_traits<rectangle_type>::coordinate_type> (xh(rectangle), yh(rectangle));
+    return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yh(rectangle));
   }
 
   struct y_r_contains : gtl_yes {};
@@ -365,24 +366,25 @@
                        rectangle_type>::type &
   set_points(rectangle_type& rectangle, const point_type_1& p1,
              const point_type_2& p2) {
-    typedef typename rectangle_traits<rectangle_type>::coordinate_type Unit;
+    typedef typename rectangle_coordinate_type<rectangle_type>::type Unit;
     Unit x1(x(p1));
     Unit x2(x(p2));
     Unit y1(y(p1));
     Unit y2(y(p2));
-    horizontal(rectangle, construct<typename rectangle_traits<rectangle_type>::interval_type>(x1, x2));
-    vertical(rectangle, construct<typename rectangle_traits<rectangle_type>::interval_type>(y1, y2));
+    horizontal(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(x1, x2));
+    vertical(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(y1, y2));
     return rectangle;
   }
-  
+
+  struct y_r_move : gtl_yes {};
+
   // move rectangle by delta in orient
   template <typename rectangle_type>
-  rectangle_type&
+  typename enable_if< typename gtl_and<y_r_move, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
+                      rectangle_type>::type &
   move(rectangle_type& rectangle, orientation_2d orient, 
-       typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::coordinate_difference delta,
-       typename enable_if<typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type * = 0
-       ) {
-    typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orient);
+       typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference delta) {
+    typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
     move(ivl, delta);
     set(rectangle, orient, ivl);
     return rectangle;
@@ -399,7 +401,7 @@
     rectangle_type_1>::type &
   convolve(rectangle_type_1& rectangle,
            const rectangle_type_2& convolution_rectangle) {
-    typename rectangle_traits<rectangle_type_1>::interval_type ivl = horizontal(rectangle);
+    typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
     horizontal(rectangle, convolve(ivl, horizontal(convolution_rectangle)));
     ivl = vertical(rectangle);
     vertical(rectangle, convolve(ivl, vertical(convolution_rectangle)));
@@ -415,7 +417,7 @@
     typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
                        rectangle_type_1>::type &
   deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) {
-    typename rectangle_traits<rectangle_type_1>::interval_type ivl = horizontal(rectangle);
+    typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
     horizontal(rectangle, deconvolve(ivl, horizontal(convolution_rectangle)));
     ivl = vertical(rectangle);
     vertical(rectangle, deconvolve(ivl, vertical(convolution_rectangle)));
@@ -431,7 +433,7 @@
                       typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
     rectangle_type_1>::type &
   reflected_convolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) {
-    typename rectangle_traits<rectangle_type_1>::interval_type ivl = horizontal(rectangle);
+    typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
     horizontal(rectangle, reflected_convolve(ivl, horizontal(convolution_rectangle)));
     ivl = vertical(rectangle);
     vertical(rectangle, reflected_convolve(ivl, vertical(convolution_rectangle)));
@@ -448,7 +450,7 @@
                       typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
     rectangle_type_1>::type &
   reflected_deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) {
-    typename rectangle_traits<rectangle_type_1>::interval_type ivl = horizontal(rectangle);
+    typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
     horizontal(rectangle, reflected_deconvolve(ivl, horizontal(convolution_rectangle)));
     ivl = vertical(rectangle);
     vertical(rectangle, reflected_deconvolve(ivl, vertical(convolution_rectangle)));
@@ -463,7 +465,7 @@
                                          typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
                        rectangle_type>::type &
   convolve(rectangle_type& rectangle, const point_type& convolution_point) {
-    typename rectangle_traits<rectangle_type>::interval_type ivl = horizontal(rectangle);
+    typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle);
     horizontal(rectangle, convolve(ivl, x(convolution_point)));
     ivl = vertical(rectangle);
     vertical(rectangle, convolve(ivl, y(convolution_point)));
@@ -478,7 +480,7 @@
     typename gtl_and_3<y_r_deconvolve2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
                       typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, rectangle_type>::type &
   deconvolve(rectangle_type& rectangle, const point_type& convolution_point) {
-    typename rectangle_traits<rectangle_type>::interval_type ivl = horizontal(rectangle);
+    typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle);
     horizontal(rectangle, deconvolve(ivl, x(convolution_point)));
     ivl = vertical(rectangle);
     vertical(rectangle, deconvolve(ivl, y(convolution_point)));
@@ -489,7 +491,7 @@
 
   // get the magnitude of the interval range depending on orient
   template <typename rectangle_type>
-  typename enable_if< typename gtl_and<y_r_delta, typename gtl_if<typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
+  typename enable_if< typename gtl_and<y_r_delta, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
                        typename rectangle_difference_type<rectangle_type>::type>::type
   delta(const rectangle_type& rectangle, orientation_2d orient) {
     return delta(get(rectangle, orient));
@@ -500,9 +502,9 @@
   // get the area of the rectangle
   template <typename rectangle_type>
   typename enable_if< typename gtl_and<y_r_area, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
-                       typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::manhattan_area_type>::type
+                       typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type>::type
   area(const rectangle_type& rectangle) {
-    typedef typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::manhattan_area_type area_type;
+    typedef typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type area_type;
     return (area_type)delta(rectangle, HORIZONTAL) * (area_type)delta(rectangle, VERTICAL);
   }
 
@@ -521,18 +523,19 @@
 
   // get the half perimeter of the rectangle
   template <typename rectangle_type>
-  typename enable_if< typename gtl_and<y_r_half_p, typename gtl_if<typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type>::type,
+  typename enable_if< typename gtl_and<y_r_half_p, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
                        typename rectangle_difference_type<rectangle_type>::type>::type
   half_perimeter(const rectangle_type& rectangle) {
     return delta(rectangle, HORIZONTAL) + delta(rectangle, VERTICAL);
   }
-   
+
+  struct y_r_perimeter : gtl_yes {};
+
   // get the perimeter of the rectangle
   template <typename rectangle_type>
-  typename rectangle_difference_type<rectangle_type>::type
-  perimeter(const rectangle_type& rectangle,
-  typename enable_if< typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and<y_r_perimeter, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
+                      typename rectangle_difference_type<rectangle_type>::type>::type
+  perimeter(const rectangle_type& rectangle) {
     return 2 * half_perimeter(rectangle);
   }
 
@@ -623,7 +626,7 @@
     bool>::type 
   intersect(rectangle_type& rectangle, const interval_type& b,
             orientation_2d orient, bool consider_touch = true) {
-    typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orient);
+    typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
     if(intersect(ivl, b, consider_touch)) {
       set(rectangle, orient, ivl);
       return true;
@@ -656,7 +659,7 @@
     typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
                        rectangle_type_1>::type &
   generalized_intersect(rectangle_type_1& rectangle, const rectangle_type_2& b) {
-    typename rectangle_traits<rectangle_type_1>::interval_type ivl = get(rectangle, HORIZONTAL);
+    typename rectangle_interval_type<rectangle_type_1>::type ivl = get(rectangle, HORIZONTAL);
     generalized_intersect(ivl, horizontal(b));
     horizontal(rectangle, ivl);
     ivl = vertical(rectangle);
@@ -672,8 +675,8 @@
   typename enable_if<typename gtl_and<y_r_bloat, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                       rectangle_type>::type &
   bloat(rectangle_type& rectangle, orientation_2d orient, 
-        typename rectangle_traits<rectangle_type>::coordinate_type bloating) {
-    typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orient);
+        typename rectangle_coordinate_type<rectangle_type>::type bloating) {
+    typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
     bloat(ivl, bloating);
     set(rectangle, orient, ivl);
     return rectangle;
@@ -686,7 +689,7 @@
   typename enable_if<typename gtl_and<y_r_bloat2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                       rectangle_type>::type &
   bloat(rectangle_type& rectangle,
-        typename rectangle_traits<rectangle_type>::coordinate_type bloating) {
+        typename rectangle_coordinate_type<rectangle_type>::type bloating) {
     bloat(rectangle, HORIZONTAL, bloating);
     return bloat(rectangle, VERTICAL, bloating);
   }
@@ -698,8 +701,8 @@
   typename enable_if<typename gtl_and<y_r_bloat3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                       rectangle_type>::type &
   bloat(rectangle_type& rectangle, direction_2d dir,
-        typename rectangle_traits<rectangle_type>::coordinate_type bloating) {
-    typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orientation_2d(dir));
+        typename rectangle_coordinate_type<rectangle_type>::type bloating) {
+    typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orientation_2d(dir));
     bloat(ivl, direction_1d(dir), bloating);
     set(rectangle, orientation_2d(dir), ivl);
     return rectangle;
@@ -712,7 +715,7 @@
   typename enable_if<typename gtl_and<y_r_shrink, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                       rectangle_type>::type &
   shrink(rectangle_type& rectangle, orientation_2d orient, 
-         typename rectangle_traits<rectangle_type>::coordinate_type shrinking) {
+         typename rectangle_coordinate_type<rectangle_type>::type shrinking) {
     return bloat(rectangle, orient, -shrinking);
   }
 
@@ -723,7 +726,7 @@
   typename enable_if<typename gtl_and<y_r_shrink2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                       rectangle_type>::type &
   shrink(rectangle_type& rectangle, 
-         typename rectangle_traits<rectangle_type>::coordinate_type shrinking) {
+         typename rectangle_coordinate_type<rectangle_type>::type shrinking) {
     return bloat(rectangle, -shrinking);
   }
 
@@ -734,7 +737,7 @@
   typename enable_if<typename gtl_and<y_r_shrink3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                       rectangle_type>::type &
   shrink(rectangle_type& rectangle, direction_2d dir,
-         typename rectangle_traits<rectangle_type>::coordinate_type shrinking) {
+         typename rectangle_coordinate_type<rectangle_type>::type shrinking) {
     return bloat(rectangle, dir, -shrinking);
   }
 
@@ -742,13 +745,13 @@
 
   // encompass interval on orient
   template <typename rectangle_type, typename interval_type>
-  typename enable_if<
-    typename gtl_and_3<y_r_encompass, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
-                      typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
-    bool>::type 
-  encompass(rectangle_type& rectangle, const interval_type& b,
-            orientation_2d orient) {
-    typename rectangle_traits<rectangle_type>::interval_type ivl = get(rectangle, orient);
+  typename enable_if<typename gtl_and_3<
+        y_r_encompass,
+        typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
+        typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
+      bool>::type 
+  encompass(rectangle_type& rectangle, const interval_type& b, orientation_2d orient) {
+    typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
     if(encompass(ivl, b)) {
       set(rectangle, orient, ivl);
       return true;
@@ -760,12 +763,12 @@
 
   // enlarge rectangle to encompass the Rectangle b
   template <typename rectangle_type_1, typename rectangle_type_2>
-  bool 
-  encompass(rectangle_type_1& rectangle, const rectangle_type_2& b,
-    typename enable_if< typename gtl_and_3<y_r_encompass2,
-            typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
-            typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type >::type>::type * = 0
-  ) {
+  typename enable_if< typename gtl_and_3<
+        y_r_encompass2,
+        typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
+        typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type >::type,
+      bool>::type
+  encompass(rectangle_type_1& rectangle, const rectangle_type_2& b) {
     //note that operator | is intentional because both should be called regardless
     return encompass(rectangle, horizontal(b), HORIZONTAL) |
       encompass(rectangle, vertical(b), VERTICAL);
@@ -775,16 +778,13 @@
 
   // enlarge rectangle to encompass the point b
   template <typename rectangle_type_1, typename point_type>
-  typename enable_if<
-    typename gtl_and_3<y_r_encompass3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
-                      typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
-    bool>::type 
-  encompass(rectangle_type_1& rectangle, const point_type& b,
-    typename enable_if<
-    typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
-            typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type>::type * = 0
-  ) {
-    typename rectangle_traits<rectangle_type_1>::interval_type hivl, vivl;
+  typename enable_if<typename gtl_and_3<
+        y_r_encompass3,
+        typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
+        typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
+      bool>::type 
+  encompass(rectangle_type_1& rectangle, const point_type& b) {
+    typename rectangle_interval_type<rectangle_type_1>::type hivl, vivl;
     hivl = horizontal(rectangle);
     vivl = vertical(rectangle);
     //note that operator | is intentional because both should be called regardless
@@ -818,7 +818,7 @@
                       typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
     bool>::type 
   get_corner(point_type& corner_point, const rectangle_type& rectangle, direction_2d direction_facing, direction_1d direction_turning) {
-    typedef typename rectangle_traits<rectangle_type>::coordinate_type Unit;
+    typedef typename rectangle_coordinate_type<rectangle_type>::type Unit;
     Unit u1 = get(rectangle, direction_facing);
     Unit u2 = get(rectangle, direction_facing.turn(direction_turning));
     if(orientation_2d(direction_facing).to_int()) std::swap(u1, u2);
@@ -844,8 +844,8 @@
                                          typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
                        bool>::type 
   join_with(rectangle_type_1& rectangle, const rectangle_type_2& b) {
-    typedef typename rectangle_traits<rectangle_type_1>::interval_type Interval1;
-    typedef typename rectangle_traits<rectangle_type_2>::interval_type Interval2;
+    typedef typename rectangle_interval_type<rectangle_type_1>::type Interval1;
+    typedef typename rectangle_interval_type<rectangle_type_2>::type Interval2;
     Interval1 hi1 = get(rectangle, HORIZONTAL);
     Interval1 vi1 = get(rectangle, VERTICAL);
     Interval2 hi2 = get(b, HORIZONTAL), vi2 = get(b, VERTICAL);
@@ -887,12 +887,12 @@
   struct y_r_sed : gtl_yes {};
 
   template <typename rectangle_type, typename point_type>
-  typename enable_if< typename gtl_if< typename gtl_and_3<y_r_sed,
+  typename enable_if< typename gtl_and_3<y_r_sed,
     typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
-    typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type>::type,
+    typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
                        typename rectangle_difference_type<rectangle_type>::type>::type
   square_euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) {
-    typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::coordinate_difference xdist, ydist;
+    typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
     xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
     ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
     return (xdist * xdist) + (ydist * ydist);
@@ -906,7 +906,7 @@
                                        typename is_rectangle_concept< typename geometry_concept<rectangle_type_2>::type>::type>::type, 
     typename rectangle_difference_type<rectangle_type>::type>::type
   square_euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) {
-    typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::coordinate_difference xdist, ydist;
+    typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
     xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
     ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
     return (xdist * xdist) + (ydist * ydist);
@@ -942,7 +942,7 @@
                                        typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
     typename rectangle_difference_type<rectangle_type>::type>::type
   manhattan_distance(rectangle_type& lvalue, const point_type& rvalue) {
-    typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::coordinate_difference xdist, ydist;
+    typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
     xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
     ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
     return xdist + ydist;
@@ -956,7 +956,7 @@
                                        typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
     typename rectangle_difference_type<rectangle_type>::type>::type
   manhattan_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) {
-    typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::coordinate_difference xdist, ydist;
+    typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
     xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
     ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
     return xdist + ydist;
@@ -968,7 +968,7 @@
   typename enable_if<typename gtl_and<y_r_scale_up, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                      rectangle_type>::type &
   scale_up(rectangle_type& rectangle, 
-           typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::unsigned_area_type factor) {
+           typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) {
     horizontal(rectangle, scale_up(horizontal(rectangle), factor));
     vertical(rectangle, scale_up(vertical(rectangle), factor));
     return rectangle;
@@ -980,7 +980,7 @@
   typename enable_if<typename gtl_and<y_r_scale_down, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                      rectangle_type>::type &
   scale_down(rectangle_type& rectangle, 
-             typename coordinate_traits<typename rectangle_traits<rectangle_type>::coordinate_type>::unsigned_area_type factor) {
+             typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) {
     horizontal(rectangle, scale_down(horizontal(rectangle), factor));
     vertical(rectangle, scale_down(vertical(rectangle), factor));
     return rectangle;
@@ -992,8 +992,8 @@
   typename enable_if<typename gtl_and<y_r_scale, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                      rectangle_type>::type &
   scale(rectangle_type& rectangle, const scaling_type& scaling) {
-    point_data<typename rectangle_traits<rectangle_type>::coordinate_type> llp(xl(rectangle), yl(rectangle));
-    point_data<typename rectangle_traits<rectangle_type>::coordinate_type> urp(xl(rectangle), yl(rectangle));
+    point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle));
+    point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xl(rectangle), yl(rectangle));
     scale(llp, scaling);
     scale(urp, scaling);
     set_points(rectangle, llp, urp);
@@ -1006,8 +1006,8 @@
   typename enable_if<typename gtl_and<y_r_transform, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, 
                      rectangle_type>::type &
   transform(rectangle_type& rectangle, const transformation_type& transformation) {
-    point_data<typename rectangle_traits<rectangle_type>::coordinate_type> llp(xl(rectangle), yl(rectangle));
-    point_data<typename rectangle_traits<rectangle_type>::coordinate_type> urp(xh(rectangle), yh(rectangle));
+    point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle));
+    point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xh(rectangle), yh(rectangle));
     transform(llp, transformation);
     transform(urp, transformation);
     set_points(rectangle, llp, urp);
@@ -1026,7 +1026,7 @@
       bool>::type 
     operator () (const rectangle_type_1& a,
                  const rectangle_type_2& b) const {
-      typedef typename rectangle_traits<rectangle_type_1>::coordinate_type Unit;
+      typedef typename rectangle_coordinate_type<rectangle_type_1>::type Unit;
       Unit vl1 = get(get(a, orient_), LOW); 
       Unit vl2 = get(get(b, orient_), LOW); 
       if(vl1 > vl2) return false;
Added: trunk/boost/polygon/segment_concept.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/segment_concept.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,735 @@
+/*
+  Copyright 2008 Intel Corporation
+
+  Use, modification and distribution are subject to the Boost Software License,
+  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+  http://www.boost.org/LICENSE_1_0.txt).
+*/
+#ifndef BOOST_POLYGON_SEGMENT_CONCEPT_HPP
+#define BOOST_POLYGON_SEGMENT_CONCEPT_HPP
+#include "isotropy.hpp"
+#include "segment_data.hpp"
+#include "segment_traits.hpp"
+#include "rectangle_concept.hpp"
+#include "detail/polygon_arbitrary_formation.hpp"
+
+namespace boost { namespace polygon{
+  struct segment_concept {};
+
+  template <typename Segment>
+  struct is_segment_concept { typedef gtl_no type; };
+
+  template <>
+  struct is_segment_concept<segment_concept> {
+    typedef gtl_yes type;
+  };
+
+  template <typename Segment>
+  struct is_mutable_segment_concept { typedef gtl_no type; };
+
+  template <>
+  struct is_mutable_segment_concept<segment_concept> {
+    typedef gtl_yes type;
+  };
+
+  template <typename Segment, typename CT>
+  struct segment_distance_type_by_concept {
+    typedef void type;
+  };
+
+  template <typename Segment>
+  struct segment_distance_type_by_concept<Segment, gtl_yes> {
+    typedef typename coordinate_traits<
+      typename segment_traits<Segment>::coordinate_type
+    >::coordinate_distance type;
+  };
+
+  template <typename Segment>
+  struct segment_distance_type {
+    typedef typename segment_distance_type_by_concept<
+      Segment,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type type;
+  };
+
+  template <typename Segment, typename CT>
+  struct segment_point_type_by_concept { typedef void type; };
+
+  template <typename Segment>
+  struct segment_point_type_by_concept<Segment, gtl_yes> {
+    typedef typename segment_traits<Segment>::point_type type;
+  };
+
+  template <typename Segment>
+  struct segment_point_type {
+    typedef typename segment_point_type_by_concept<
+      Segment,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type type;
+  };
+
+  template <typename Segment, typename CT>
+  struct segment_coordinate_type_by_concept {
+    typedef void type;
+  };
+
+  template <typename Segment>
+  struct segment_coordinate_type_by_concept<Segment, gtl_yes> {
+    typedef typename segment_traits<Segment>::coordinate_type type;
+  };
+
+  template <typename Segment>
+  struct segment_coordinate_type {
+    typedef typename segment_coordinate_type_by_concept<
+      Segment,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type type;
+  };
+
+  struct y_s_get : gtl_yes {};
+
+  template <typename Segment>
+  typename enable_if<
+    typename gtl_and<
+      y_s_get,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    typename segment_point_type<Segment>::type
+  >::type
+  get(const Segment& segment, direction_1d dir) {
+    return segment_traits<Segment>::get(segment, dir);
+  }
+
+  struct y_s_set : gtl_yes {};
+
+  template <typename Segment, typename Point>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_set,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point>::type
+      >::type
+    >::type,
+    void
+  >::type
+  set(Segment& segment, direction_1d dir, const Point& point) {
+    segment_mutable_traits<Segment>::set(segment, dir, point);
+  }
+
+  struct y_s_construct : gtl_yes {};
+
+  template <typename Segment, typename Point1, typename Point2>
+  typename enable_if<
+    typename gtl_and_4<
+      y_s_construct,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point1>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point2>::type
+      >::type
+    >::type,
+    Segment
+  >::type
+  construct(const Point1& low, const Point2& high) {
+    return segment_mutable_traits<Segment>::construct(low, high);
+  }
+
+  struct y_s_copy_construct : gtl_yes {};
+
+  template <typename Segment1, typename Segment2>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_copy_construct,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment1>::type
+      >::type,
+      typename is_segment_concept<
+        typename geometry_concept<Segment2>::type
+      >::type
+    >::type,
+    Segment1
+  >::type
+  copy_construct(const Segment2& segment) {
+    return construct<Segment1>(get(segment, LOW), get(segment, HIGH));
+  }
+
+  struct y_s_assign : gtl_yes {};
+
+  template <typename Segment1, typename Segment2>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_assign,
+        typename is_mutable_segment_concept<
+          typename geometry_concept<Segment1>::type
+        >::type,
+        typename is_segment_concept<
+          typename geometry_concept<Segment2>::type
+        >::type
+    >::type,
+    Segment1
+  >::type &
+  assign(Segment1& segment1, const Segment2& segment2) {
+    return segment1 = copy_construct<Segment1>(segment2);
+  }
+
+  struct y_s_equivalence : gtl_yes {};
+
+  template <typename Segment1, typename Segment2>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_equivalence,
+      typename is_segment_concept<
+        typename geometry_concept<Segment1>::type
+      >::type,
+      typename is_segment_concept<
+        typename geometry_concept<Segment2>::type
+      >::type
+    >::type,
+    bool
+  >::type
+  equivalence(const Segment1& segment1, const Segment2& segment2) {
+    return get(segment1, LOW) == get(segment2, LOW) &&
+           get(segment1, HIGH) == get(segment2, HIGH);
+  }
+
+  struct y_s_low : gtl_yes {};
+
+  template <typename Segment>
+  typename enable_if<
+    typename gtl_and<
+      y_s_low,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    typename segment_point_type<Segment>::type
+  >::type
+  low(const Segment& segment) {
+    return get(segment, LOW);
+  }
+
+  struct y_s_high : gtl_yes {};
+
+  template <typename Segment>
+  typename enable_if<
+    typename gtl_and<
+      y_s_high,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    typename segment_point_type<Segment>::type
+  >::type
+  high(const Segment& segment) {
+    return get(segment, HIGH);
+  }
+
+  struct y_s_center : gtl_yes {};
+
+  template <typename Segment>
+  typename enable_if<
+    typename gtl_and<
+      y_s_center,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    typename segment_point_type<Segment>::type
+  >::type
+  center(const Segment& segment) {
+    return construct<typename segment_point_type<Segment>::type>(
+        (x(high(segment)) + x(low(segment)))/2,
+        (y(high(segment)) + y(low(segment)))/2);
+  }
+
+  struct y_s_low2 : gtl_yes {};
+
+  template <typename Segment, typename Point>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_low2,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point>::type
+      >::type
+    >::type,
+    void
+  >::type
+  low(Segment& segment, const Point& point) {
+    set(segment, LOW, point);
+  }
+
+  struct y_s_high2 : gtl_yes {};
+
+  template <typename Segment, typename Point>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_high2,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point>::type
+      >::type
+    >::type,
+    void
+  >::type
+  high(Segment& segment, const Point& point) {
+    set(segment, HIGH, point);
+  }
+
+  struct y_s_on_above_or_below : gtl_yes {};
+
+  // -1 for below, 0 for on and 1 for above
+  template <typename Segment, typename Point>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_on_above_or_below,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point>::type
+      >::type
+    >::type,
+    int
+  >::type
+  on_above_or_below(const Segment& segment, const Point& point) {
+    typedef polygon_arbitrary_formation<
+      typename segment_coordinate_type<Segment>::type
+    > paf;
+    typename paf::Point pt, l, h;
+    assign(pt, point);
+    assign(l, low(segment));
+    assign(h, high(segment));
+    return paf::on_above_or_below(pt, typename paf::half_edge(l, h));
+  }
+
+  struct y_s_contains : gtl_yes {};
+
+  template <typename Segment, typename Point>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_contains,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point>::type
+      >::type
+    >::type,
+    bool
+  >::type
+  contains(const Segment& segment, const Point& point, bool consider_touch = true ) {
+    if (!on_above_or_below(segment, point)) {
+      rectangle_data<typename segment_coordinate_type<Segment>::type> rect;
+      set_points(rect, low(segment), high(segment));
+      if (area(rect) == 0.0) {
+        if (!consider_touch) {
+          return !equivalence(point, low(segment)) &&
+                 !equivalence(point, high(segment));
+        }
+      }
+      return contains(rect, point, consider_touch);
+    }
+    return false;
+  }
+
+  struct y_s_contains2 : gtl_yes {};
+
+  template <typename Segment1, typename Segment2>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_contains2,
+      typename is_segment_concept<
+        typename geometry_concept<Segment1>::type
+      >::type,
+      typename is_segment_concept<
+        typename geometry_concept<Segment2>::type
+      >::type
+    >::type,
+    bool
+  >::type
+  contains(const Segment1& segment1, const Segment2& segment2, bool consider_touch = true) {
+    return contains(segment1, get(segment2, LOW), consider_touch) &&
+           contains(segment1, get(segment2, HIGH), consider_touch);
+  }
+
+  struct y_s_length : gtl_yes {};
+
+  template <typename Segment>
+  typename enable_if<
+    typename gtl_and<
+      y_s_length,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    typename segment_distance_type<Segment>::type
+  >::type
+  length(const Segment& segment) {
+    return euclidean_distance(low(segment), high(segment));
+  }
+
+  struct y_s_scale_up : gtl_yes {};
+
+  template <typename Segment>
+  typename enable_if<
+    typename gtl_and<
+      y_s_scale_up,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    Segment
+  >::type &
+  scale_up(Segment& segment,
+           typename coordinate_traits<
+             typename segment_coordinate_type<Segment>::type
+           >::unsigned_area_type factor) {
+    typename segment_point_type<Segment>::type l = low(segment), h = high(segment);
+    low(segment, scale_up(l, factor));
+    high(segment, scale_up(h, factor));
+    return segment;
+  }
+
+  struct y_s_scale_down : gtl_yes {};
+
+  template <typename Segment>
+  typename enable_if<
+    typename gtl_and<
+      y_s_scale_down,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    Segment
+  >::type &
+  scale_down(Segment& segment,
+             typename coordinate_traits<
+               typename segment_coordinate_type<Segment>::type
+             >::unsigned_area_type factor) {
+    typename segment_point_type<Segment>::type l = low(segment), h = high(segment);
+    low(segment, scale_down(l, factor));
+    high(segment, scale_down(h, factor));
+    return segment;
+  }
+
+  struct y_s_scale : gtl_yes {};
+
+  template <typename Segment, typename Scale>
+  typename enable_if<
+    typename gtl_and<
+      y_s_scale,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    Segment
+  >::type &
+  scale(Segment& segment, const Scale& sc) {
+    typename segment_point_type<Segment>::type l = low(segment), h = high(segment);
+    low(segment, scale(l, sc));
+    high(segment, scale(h, sc));
+    return segment;
+  }
+
+  struct y_s_transform : gtl_yes {};
+
+  template <typename Segment, typename Transform>
+  typename enable_if<
+    typename gtl_and<
+      y_s_transform,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    Segment
+  >::type &
+  transform(Segment& segment, const Transform& tr) {
+    typename segment_point_type<Segment>::type l = low(segment), h = high(segment);
+    low(segment, transform(l, tr));
+    high(segment, transform(h, tr));
+    return segment;
+  }
+
+  struct y_s_move : gtl_yes {};
+
+  template <typename Segment>
+  typename enable_if<
+    typename gtl_and<
+      y_s_move,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type
+    >::type,
+    Segment
+  >::type &
+  move(Segment& segment, orientation_2d orient,
+       typename segment_coordinate_type<Segment>::type displacement) {
+    typename segment_point_type<Segment>::type l = low(segment), h = high(segment);
+    low(segment, move(l, orient, displacement));
+    high(segment, move(h, orient, displacement));
+    return segment;
+  }
+
+  struct y_s_convolve : gtl_yes {};
+
+  template <typename Segment, typename Point>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_convolve,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point>::type
+      >::type
+    >::type,
+    Segment
+  >::type &
+  convolve(Segment& segment, const Point& point) {
+    typename segment_point_type<Segment>::type l = low(segment), h = high(segment);
+    low(segment, convolve(l, point));
+    high(segment, convolve(h, point));
+    return segment;
+  }
+
+  struct y_s_deconvolve : gtl_yes {};
+
+  template <typename Segment, typename Point>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_deconvolve,
+      typename is_mutable_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point>::type
+      >::type
+    >::type,
+    Segment
+  >::type &
+  deconvolve(Segment& segment, const Point& point) {
+    typename segment_point_type<Segment>::type l = low(segment), h = high(segment);
+    low(segment, deconvolve(l, point));
+    high(segment, deconvolve(h, point));
+    return segment;
+  }
+
+  struct y_s_abuts1 : gtl_yes {};
+
+  template <typename Segment1, typename Segment2>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_abuts1,
+      typename is_segment_concept<
+        typename geometry_concept<Segment1>::type
+      >::type,
+      typename is_segment_concept<
+        typename geometry_concept<Segment2>::type
+      >::type
+    >::type,
+    bool
+  >::type
+  abuts(const Segment1& segment1, const Segment2& segment2, direction_1d dir) {
+    return dir.to_int() ? equivalence(low(segment2) , high(segment1)) :
+                          equivalence(low(segment1) , high(segment2));
+  }
+
+  struct y_s_abuts2 : gtl_yes {};
+
+  template <typename Segment1, typename Segment2>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_abuts2,
+      typename is_segment_concept<
+        typename geometry_concept<Segment1>::type
+      >::type,
+      typename is_segment_concept<
+        typename geometry_concept<Segment2>::type
+      >::type
+    >::type,
+    bool
+  >::type
+  abuts(const Segment1& segment1, const Segment2& segment2) {
+    return abuts(segment1, segment2, HIGH) || abuts(segment1, segment2, LOW);
+  }
+
+  struct y_s_e_intersects : gtl_yes {};
+
+  template <typename Segment1, typename Segment2>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_e_intersects,
+      typename is_segment_concept<
+        typename geometry_concept<Segment1>::type
+      >::type,
+      typename is_segment_concept<
+        typename geometry_concept<Segment2>::type
+      >::type
+    >::type,
+    bool
+  >::type
+  intersects(const Segment1& segment1, const Segment2& segment2,
+             bool consider_touch = true) {
+    if (consider_touch) {
+      if (low(segment1) == low(segment2) || low(segment1) == high(segment2) ||
+          high(segment1) == low(segment2) || high(segment1) == high(segment2))
+        return true;
+    }
+    typedef polygon_arbitrary_formation<
+      typename segment_coordinate_type<Segment1>::type
+    > paf;
+    typename paf::Point l1, h1, l2, h2;
+    assign(l1, low(segment1));
+    assign(h1, high(segment1));
+    assign(l2, low(segment2));
+    assign(h2, high(segment2));
+    return paf::intersects(typename paf::half_edge(l1, h1),
+                           typename paf::half_edge(l2, h2));
+  }
+
+  struct y_s_intersect : gtl_yes {};
+
+  // Set point to the intersection of segment and b
+  template <typename Point, typename Segment1, typename Segment2>
+  typename enable_if<
+    typename gtl_and_4<
+      y_s_intersect,
+      typename is_mutable_point_concept<
+        typename geometry_concept<Point>::type
+      >::type,
+      typename is_segment_concept<
+        typename geometry_concept<Segment1>::type
+      >::type,
+      typename is_segment_concept<
+        typename geometry_concept<Segment2>::type
+      >::type
+    >::type,
+    bool
+  >::type
+  intersection(Point& intersection,
+               const Segment1& segment1,
+               const Segment2& segment2,
+               bool projected = false,
+               bool round_closest = false) {
+    typedef polygon_arbitrary_formation<
+      typename segment_coordinate_type<Segment1>::type
+    > paf;
+    typename paf::Point pt;
+    typename paf::Point l1, h1, l2, h2;
+    assign(l1, low(segment1));
+    assign(h1, high(segment1));
+    assign(l2, low(segment2));
+    assign(h2, high(segment2));
+    typename paf::half_edge he1(l1, h1), he2(l2, h2);
+    typename paf::compute_intersection_pack pack;
+    if (pack.compute_intersection(pt, he1, he2, projected, round_closest)) {
+      assign(intersection, pt);
+      return true;
+    }
+    return false;
+  }
+
+  struct y_s_e_dist : gtl_yes {};
+
+  template <typename Segment, typename Point>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_e_dist,
+      typename is_segment_concept<
+        typename geometry_concept<Segment>::type
+      >::type,
+      typename is_point_concept<
+        typename geometry_concept<Point>::type
+      >::type
+    >::type,
+    typename segment_distance_type<Segment>::type
+  >::type
+  euclidean_distance(const Segment& segment, const Point& point) {
+    typedef typename segment_distance_type<Segment>::type Unit;
+    Unit x1 = x(low(segment));
+    Unit y1 = y(low(segment));
+    Unit x2 = x(high(segment));
+    Unit y2 = y(high(segment));
+    Unit X = x(point);
+    Unit Y = y(point);
+    Unit A = X - x1;
+    Unit B = Y - y1;
+    Unit C = x2 - x1;
+    Unit D = y2 - y1;
+    Unit param = (A * C + B * D);
+    Unit length_sq = C * C + D * D;
+    if (param > length_sq) {
+      return euclidean_distance(high(segment), point);
+    } else if (param < 0.0) {
+      return euclidean_distance(low(segment), point);
+    }
+    if (length_sq == 0.0)
+      return 0.0;
+    Unit denom = sqrt(length_sq);
+    Unit result = (A * D - C * B) / denom;
+    return (result < 0.0) ? -result : result;
+  }
+
+  struct y_s_e_dist2 : gtl_yes {};
+
+  template <typename Segment1, typename Segment2>
+  typename enable_if<
+    typename gtl_and_3<
+      y_s_e_dist2,
+      typename is_segment_concept<
+        typename geometry_concept<Segment1>::type
+      >::type,
+      typename is_segment_concept<
+        typename geometry_concept<Segment2>::type
+      >::type
+    >::type,
+    typename segment_distance_type<Segment1>::type
+  >::type
+  euclidean_distance(const Segment1& segment1, const Segment2& segment2) {
+    if (intersects(segment1, segment2))
+      return 0.0;
+    typename segment_distance_type<Segment1>::type
+        result1 = euclidean_distance(segment1, low(segment2)),
+        result2 = euclidean_distance(segment1, high(segment2)),
+        result3 = euclidean_distance(segment2, low(segment1)),
+        result4 = euclidean_distance(segment2, high(segment1));
+    typename segment_distance_type<Segment1>::type
+        subres1 = (result1 < result2) ? result1 : result2,
+        subres2 = (result3 < result4) ? result3 : result4;
+    return (subres1 < subres2) ? subres1 : subres2;
+  }
+
+  template <class T>
+  template <class Segment>
+  segment_data<T>& segment_data<T>::operator=(const Segment& rvalue) {
+    assign(*this, rvalue);
+    return *this;
+  }
+
+  template <typename T>
+  struct geometry_concept<segment_data<T> > {
+    typedef segment_concept type;
+  };
+}
+}
+#endif
Added: trunk/boost/polygon/segment_data.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/segment_data.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,106 @@
+/*
+  Copyright 2008 Intel Corporation
+
+  Use, modification and distribution are subject to the Boost Software License,
+  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+  http://www.boost.org/LICENSE_1_0.txt).
+*/
+#ifndef BOOST_POLYGON_SEGMENT_DATA_HPP
+#define BOOST_POLYGON_SEGMENT_DATA_HPP
+
+#include "isotropy.hpp"
+
+namespace boost { namespace polygon{
+  template <typename T>
+  class segment_data {
+  public:
+    typedef T coordinate_type;
+    typedef point_data<T> point_type;
+
+    inline segment_data()
+#ifndef BOOST_POLYGON_MSVC
+      :points_()
+#endif
+    {}
+
+    inline segment_data(const point_type& low, const point_type& high)
+#ifndef BOOST_POLYGON_MSVC
+      :points_()
+#endif
+    {
+      points_[LOW] = low; points_[HIGH] = high;
+    }
+
+    inline segment_data(const segment_data& that)
+#ifndef BOOST_POLYGON_MSVC
+      :points_()
+#endif
+    {
+      (*this) = that;
+    }
+
+    inline segment_data& operator=(const segment_data& that) {
+      points_[0] = that.points_[0];
+      points_[1] = that.points_[1];
+      return *this;
+    }
+
+    template <typename Segment>
+    inline segment_data& operator=(const Segment& that);
+
+    inline point_type get(direction_1d dir) const {
+      return points_[dir.to_int()];
+    }
+
+    inline void set(direction_1d dir, const point_type& point) {
+      points_[dir.to_int()] = point;
+    }
+
+    inline point_type low() const { return points_[0]; }
+
+    inline segment_data& low(const point_type& point) {
+      points_[0] = point;
+      return *this;
+    }
+
+    inline point_type high() const {return points_[1]; }
+
+    inline segment_data& high(const point_type& point) {
+      points_[1] = point;
+      return *this;
+    }
+
+    inline bool operator==(const segment_data& that) const {
+      return low() == that.low() && high() == that.high();
+    }
+
+    inline bool operator!=(const segment_data& that) const {
+      return low() != that.low() || high() != that.high();
+    }
+
+    inline bool operator<(const segment_data& that) const {
+      if (points_[0] < that.points_[0])
+        return true;
+      if (points_[0] > that.points_[0])
+        return false;
+      return points_[1] < that.points_[1];
+    }
+
+    inline bool operator<=(const segment_data& that) const {
+      return !(that < *this);
+    }
+
+    inline bool operator>(const segment_data& that) const {
+      return that < *this;
+    }
+
+    inline bool operator>=(const segment_data& that) const {
+      return !((*this) < that);
+    }
+
+  private:
+    point_type points_[2];
+};
+}
+}
+#endif
Added: trunk/boost/polygon/segment_traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/segment_traits.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,35 @@
+/*
+  Copyright 2008 Intel Corporation
+
+  Use, modification and distribution are subject to the Boost Software License,
+  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+  http://www.boost.org/LICENSE_1_0.txt).
+*/
+#ifndef BOOST_POLYGON_SEGMENT_TRAITS_HPP
+#define BOOST_POLYGON_SEGMENT_TRAITS_HPP
+namespace boost { namespace polygon{
+  template <typename Segment>
+  struct segment_traits {
+    typedef typename Segment::coordinate_type coordinate_type;
+    typedef typename Segment::point_type point_type;
+
+    static inline point_type get(const Segment& segment, direction_1d dir) {
+      return segment.get(dir);
+    }
+  };
+
+  template <typename Segment>
+  struct segment_mutable_traits {
+    typedef typename segment_traits<Segment>::point_type point_type;
+
+    static inline void set(Segment& segment, direction_1d dir, const point_type& point) {
+      segment.set(dir, point);
+    }
+
+    static inline Segment construct(const point_type& low, const point_type& high) {
+      return Segment(low, high);
+    }
+  };
+}
+}
+#endif
Added: trunk/boost/polygon/voronoi.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/voronoi.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,164 @@
+// Boost.Polygon library voronoi.hpp header file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POLYGON_VORONOI
+#define BOOST_POLYGON_VORONOI
+
+#include "polygon.hpp"
+#include "voronoi_builder.hpp"
+#include "voronoi_diagram.hpp"
+
+// Public methods to compute Voronoi diagram.
+// PC - container of input points (should supports forward iterator).
+// SC - container of input segments (should supports forward iterator).
+// output - Voronoi output data structure to hold Voronoi diagram.
+// Segment class should provide low(), high() methods to access its endpoints.
+// The assumption is made that input doesn't contain segments that intersect
+// or points lying on the segments. Also coordinates of the points and of the
+// endpoints of the segments should belong to the signed integer range
+// [-2^31, 2^31-1]. To use wider input coordinate range use voronoi_builder
+// structure with user provided coordinate type traits.
+// Complexity - O(N*logN), memory usage - O(N),
+// where N is the total number of points and segments.
+namespace boost {
+namespace polygon {
+
+template <typename Point, typename VB>
+static inline
+typename enable_if<
+  typename gtl_if<
+    typename is_point_concept<
+      typename geometry_concept<Point>::type
+    >::type
+  >::type,
+  void
+>::type
+insert(const Point &point, VB *vb) {
+  vb->insert_point(x(point), y(point));
+}
+
+
+template <typename PointIterator, typename VB>
+static inline
+typename enable_if<
+  typename gtl_if<
+    typename is_point_concept<
+      typename geometry_concept<
+        typename std::iterator_traits<PointIterator>::value_type
+      >::type
+    >::type
+  >::type,
+  void
+>::type
+insert(PointIterator first, const PointIterator last, VB *vb) {
+  for (PointIterator it = first; it != last; ++it) {
+    insert(*it, vb);
+  }
+}
+
+template <typename Segment, typename VB>
+static inline
+typename enable_if<
+  typename gtl_if<
+    typename is_segment_concept<
+      typename geometry_concept<Segment>::type
+    >::type
+  >::type,
+  void
+>::type
+insert(const Segment &segment, VB *vb) {
+  vb->insert_segment(x(low(segment)), y(low(segment)), x(high(segment)), y(high(segment)));
+}
+
+template <typename SegmentIterator, typename VB>
+static inline
+typename enable_if<
+  typename gtl_if<
+    typename is_segment_concept<
+      typename geometry_concept<
+        typename std::iterator_traits<SegmentIterator>::value_type
+      >::type
+    >::type
+  >::type,
+  void
+>::type
+insert(SegmentIterator first, SegmentIterator last, VB *vb) {
+  for (SegmentIterator it = first; it != last; ++it) {
+    insert(*it, vb);
+  }
+}
+
+template <typename PointIterator, typename VD>
+static inline
+typename enable_if<
+  typename gtl_if<
+    typename is_point_concept<
+      typename geometry_concept<
+        typename std::iterator_traits<PointIterator>::value_type
+      >::type
+    >::type
+  >::type,
+  void
+>::type
+construct_voronoi(PointIterator first, PointIterator last, VD *vd) {
+  default_voronoi_builder builder;
+  insert(first, last, &builder);
+  builder.construct(vd);
+}
+
+template <typename SegmentIterator, typename VD>
+static inline
+typename enable_if<
+  typename gtl_if<
+    typename is_segment_concept<
+      typename geometry_concept<
+        typename std::iterator_traits<SegmentIterator>::value_type
+      >::type
+    >::type
+  >::type,
+  void
+>::type
+construct_voronoi(SegmentIterator first, SegmentIterator last, VD *vd) {
+  default_voronoi_builder builder;
+  insert(first, last, &builder);
+  builder.construct(vd);
+}
+
+template <typename PointIterator, typename SegmentIterator, typename VD>
+static inline 
+typename enable_if<
+  typename gtl_and<
+    typename gtl_if<
+      typename is_point_concept<
+        typename geometry_concept<
+          typename std::iterator_traits<PointIterator>::value_type
+        >::type
+      >::type
+    >::type,
+    typename gtl_if<
+      typename is_segment_concept<
+        typename geometry_concept<
+          typename std::iterator_traits<SegmentIterator>::value_type
+        >::type
+      >::type
+    >::type
+  >::type,
+  void
+>::type
+construct_voronoi(PointIterator p_first, PointIterator p_last,
+    SegmentIterator s_first, SegmentIterator s_last, VD *vd) {
+  default_voronoi_builder builder;
+  insert(p_first, p_last, &builder);
+  insert(s_first, s_last, &builder);
+  builder.construct(vd);
+}
+}  // polygon
+}  // boost
+
+#endif  // BOOST_POLYGON_VORONOI
Added: trunk/boost/polygon/voronoi_builder.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/voronoi_builder.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,506 @@
+// Boost.Polygon library voronoi_builder.hpp header file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POLYGON_VORONOI_BUILDER
+#define BOOST_POLYGON_VORONOI_BUILDER
+
+#include <algorithm>
+#include <map>
+#include <vector>
+
+#include "detail/voronoi_ctypes.hpp"
+#include "detail/voronoi_predicates.hpp"
+#include "detail/voronoi_structures.hpp"
+
+namespace boost {
+namespace polygon {
+// GENERAL INFO:
+// The sweepline algorithm implementation to compute Voronoi diagram of
+// points and non-intersecting segments (except endpoints).
+// Complexity - O(N*logN), memory usage - O(N), where N is the total number
+// of input geometries. Input geometries should have integer coordinate type.
+//
+// IMPLEMENTATION DETAILS:
+// Each input point creates one site event. Each input segment creates three
+// site events: two for its endpoints and one for the segment itself (this is
+// made to simplify output construction). All the site events are constructed
+// and sorted at the algorithm initialization step. Priority queue is used to
+// dynamically hold circle events. At each step of the algorithm execution the
+// leftmost event is retrieved by comparing the current site event and the
+// topmost element from the circle event queue. STL map (red-black tree)
+// container was chosen to hold state of the beach line. The keys of the map
+// correspond to the neighboring sites that form a bisector and values to the
+// corresponding Voronoi edge in the output data structure.
+template <typename T,
+          typename CTT = detail::voronoi_ctype_traits<T>,
+          typename VP = detail::voronoi_predicates<CTT> >
+class voronoi_builder {
+public:
+  typedef typename CTT::int_type int_type;
+  typedef typename CTT::fpt_type fpt_type;
+
+  voronoi_builder() {}
+
+  // Each point creates a single site event.
+  void insert_point(const int_type& x, const int_type& y) {
+    site_events_.push_back(site_event_type(x, y));
+  }
+
+  // Each segment creates three site events that correspond to:
+  //   1) the start point of the segment;
+  //   2) the end point of the segment;
+  //   3) the segment itself defined by its start point.
+  void insert_segment(const int_type& x1, const int_type& y1,
+                      const int_type& x2, const int_type& y2) {
+    point_type p1(x1, y1);
+    point_type p2(x2, y2);
+    site_events_.push_back(site_event_type(p1));
+    site_events_.push_back(site_event_type(p2));
+    if (point_comparison_(p1, p2)) {
+      site_events_.push_back(site_event_type(p1, p2));
+    } else {
+      site_events_.push_back(site_event_type(p2, p1));
+    }
+  }
+
+  // Run sweepline algorithm and fill output data structure.
+  template <typename OUTPUT>
+  void construct(OUTPUT *output) {
+    // Init structures.
+    output->builder()->reserve(site_events_.size());
+    init_sites_queue();
+    if (!circle_events_.empty())
+      circle_events_.clear();
+    while (!end_points_.empty())
+      end_points_.pop();
+    init_beach_line(output);
+
+    // The algorithm stops when there are no events to process.
+    event_comparison_predicate event_comparison;
+    while (!circle_events_.empty() ||
+           !(site_event_iterator_ == site_events_.end())) {
+      if (circle_events_.empty()) {
+        process_site_event(output);
+      } else if (site_event_iterator_ == site_events_.end()) {
+        process_circle_event(output);
+      } else {
+        if (event_comparison(*site_event_iterator_,
+                             circle_events_.top().first)) {
+          process_site_event(output);
+        } else {
+          process_circle_event(output);
+        }
+      }
+      while (!circle_events_.empty() &&
+             !circle_events_.top().first.is_active()) {
+        circle_events_.pop();
+      }
+    }
+    beach_line_.clear();
+
+    // Finish construction.
+    output->builder()->build();
+  }
+
+  void clear() {
+    site_events_.clear();
+    if (!beach_line_.empty())
+      beach_line_.clear();
+    if (!circle_events_.empty())
+      circle_events_.clear();
+    while (!end_points_.empty())
+      end_points_.pop();
+  }
+
+private:
+  typedef detail::point_2d<int_type> point_type;
+  typedef detail::site_event<int_type> site_event_type;
+  typedef typename std::vector<site_event_type>::const_iterator
+    site_event_iterator_type;
+  typedef detail::circle_event<fpt_type> circle_event_type;
+  typedef typename VP::template point_comparison_predicate<point_type>
+    point_comparison_predicate;
+  typedef typename VP::
+    template event_comparison_predicate<site_event_type, circle_event_type>
+    event_comparison_predicate;
+  typedef typename VP::
+    template circle_formation_predicate<site_event_type, circle_event_type>
+    circle_formation_predicate_type;
+  typedef void edge_type;
+  typedef detail::beach_line_node_key<site_event_type> key_type;
+  typedef detail::beach_line_node_data<edge_type, circle_event_type>
+    value_type;
+  typedef typename VP::template node_comparison_predicate<key_type>
+    node_comparer_type;
+  typedef std::map< key_type, value_type, node_comparer_type > beach_line_type;
+  typedef typename beach_line_type::iterator beach_line_iterator;
+  typedef std::pair<circle_event_type, beach_line_iterator> event_type;
+  typedef struct {
+    bool operator()(const event_type &lhs, const event_type &rhs) const {
+      return predicate(rhs.first, lhs.first);
+    }
+    event_comparison_predicate predicate;
+  } event_comparison_type;
+  typedef detail::ordered_queue<event_type, event_comparison_type>
+    circle_event_queue_type;
+  typedef std::pair<point_type, beach_line_iterator> end_point_type;
+
+  void init_sites_queue() {
+    // Sort site events.
+    sort(site_events_.begin(), site_events_.end(),
+        event_comparison_predicate());
+
+    // Remove duplicates.
+    site_events_.erase(unique(
+        site_events_.begin(), site_events_.end()), site_events_.end());
+
+    // Index sites.
+    for (size_t cur = 0; cur < site_events_.size(); ++cur)
+      site_events_[cur].index(cur);
+
+    // Init site iterator.
+    site_event_iterator_ = site_events_.begin();
+  }
+
+  template <typename OUTPUT>
+  void init_beach_line(OUTPUT *output) {
+    if (!beach_line_.empty())
+      beach_line_.clear();
+    if (site_events_.empty())
+      return;
+    if (site_events_.size() == 1) {
+      // Handle single site event case.
+      output->builder()->process_single_site(site_events_[0]);
+      ++site_event_iterator_;
+    } else {
+      int skip = 0;
+
+      while(site_event_iterator_ != site_events_.end() &&
+            VP::is_vertical(site_event_iterator_->point0(),
+                            site_events_.begin()->point0()) &&
+            VP::is_vertical(*site_event_iterator_)) {
+        ++site_event_iterator_;
+        ++skip;
+      }
+
+      if (skip == 1) {
+        // Init beach line with the first two sites.
+        init_beach_line_default(output);
+      } else {
+        // Init beach line with collinear vertical sites.
+        init_beach_line_collinear_sites(output);
+      }
+    }
+  }
+
+  // Init beach line with the two first sites.
+  // The first site is always a point.
+  template <typename OUTPUT>
+  void init_beach_line_default(OUTPUT *output) {
+    // Get the first and the second site event.
+    site_event_iterator_type it_first = site_events_.begin();
+    site_event_iterator_type it_second = site_events_.begin();
+    ++it_second;
+    insert_new_arc(
+        *it_first, *it_first, *it_second, beach_line_.end(), output);
+    // The second site was already processed. Move the iterator.
+    ++site_event_iterator_;
+  }
+
+  // Init beach line with collinear sites.
+  template <typename OUTPUT>
+  void init_beach_line_collinear_sites(OUTPUT *output) {
+    site_event_iterator_type it_first = site_events_.begin();
+    site_event_iterator_type it_second = site_events_.begin();
+    ++it_second;
+    while (it_second != site_event_iterator_) {
+      // Create a new beach line node.
+      key_type new_node(*it_first, *it_second);
+
+      // Update the output.
+      edge_type *edge =
+          output->builder()->insert_new_edge(*it_first, *it_second).first;
+
+      // Insert a new bisector into the beach line.
+      beach_line_.insert(beach_line_.end(),
+          std::pair<key_type, value_type>(new_node, value_type(edge)));
+
+      // Update iterators.
+      ++it_first;
+      ++it_second;
+    }
+  }
+
+  void deactivate_circle_event(value_type &value) {
+    if (value.circle_event()) {
+      value.circle_event()->deactivate();
+      value.circle_event(NULL);
+    }
+  }
+
+  template <typename OUTPUT>
+  void process_site_event(OUTPUT *output) {
+    // Get next site event to process.
+    site_event_type site_event = *site_event_iterator_;
+
+    // Move site iterator.
+    site_event_iterator_type last = site_event_iterator_ + 1;
+
+    // If a new site is an end point of some segment,
+    // remove temporary nodes from the beach line data structure.
+    if (!site_event.is_segment()) {
+      while (!end_points_.empty() &&
+             end_points_.top().first == site_event.point0()) {
+        beach_line_iterator b_it = end_points_.top().second;
+        end_points_.pop();
+        beach_line_.erase(b_it);
+      }
+    } else {
+      while (last != site_events_.end() &&
+             last->is_segment() && last->point0() == site_event.point0())
+        ++last;
+    }
+
+    // Find the node in the binary search tree with left arc
+    // lying above the new site point.
+    key_type new_key(*site_event_iterator_);
+    beach_line_iterator right_it = beach_line_.lower_bound(new_key);
+
+    for (; site_event_iterator_ != last; ++site_event_iterator_) {
+      site_event = *site_event_iterator_;
+      beach_line_iterator left_it = right_it;
+
+      // Do further processing depending on the above node position.
+      // For any two neighboring nodes the second site of the first node
+      // is the same as the first site of the second node.
+      if (right_it == beach_line_.end()) {
+        // The above arc corresponds to the second arc of the last node.
+        // Move the iterator to the last node.
+        --left_it;
+
+        // Get the second site of the last node
+        const site_event_type &site_arc = left_it->first.right_site();
+
+        // Insert new nodes into the beach line. Update the output.
+        right_it = insert_new_arc(
+            site_arc, site_arc, site_event, right_it, output);
+
+        // Add a candidate circle to the circle event queue.
+        // There could be only one new circle event formed by
+        // a new bisector and the one on the left.
+        activate_circle_event(left_it->first.left_site(),
+                              left_it->first.right_site(),
+                              site_event, right_it);
+      } else if (right_it == beach_line_.begin()) {
+        // The above arc corresponds to the first site of the first node.
+        const site_event_type &site_arc = right_it->first.left_site();
+
+        // Insert new nodes into the beach line. Update the output.
+        left_it = insert_new_arc(
+            site_arc, site_arc, site_event, right_it, output);
+
+        // If the site event is a segment, update its direction.
+        if (site_event.is_segment()) {
+          site_event.inverse();
+        }
+
+        // Add a candidate circle to the circle event queue.
+        // There could be only one new circle event formed by
+        // a new bisector and the one on the right.
+        activate_circle_event(site_event, right_it->first.left_site(),
+            right_it->first.right_site(), right_it);
+        right_it = left_it;
+      } else {
+        // The above arc corresponds neither to the first,
+        // nor to the last site in the beach line.
+        const site_event_type &site_arc2 = right_it->first.left_site();
+        const site_event_type &site3 = right_it->first.right_site();
+
+        // Remove the candidate circle from the event queue.
+        deactivate_circle_event(right_it->second);
+        --left_it;
+        const site_event_type &site_arc1 = left_it->first.right_site();
+        const site_event_type &site1 = left_it->first.left_site();
+
+        // Insert new nodes into the beach line. Update the output.
+        beach_line_iterator new_node_it =
+            insert_new_arc(site_arc1, site_arc2, site_event, right_it, output);
+
+        // Add candidate circles to the circle event queue.
+        // There could be up to two circle events formed by
+        // a new bisector and the one on the left or right.
+        activate_circle_event(site1, site_arc1, site_event, new_node_it);
+
+        // If the site event is a segment, update its direction.
+        if (site_event.is_segment()) {
+          site_event.inverse();
+        }
+        activate_circle_event(site_event, site_arc2, site3, right_it);
+        right_it = new_node_it;
+      }
+    }
+  }
+
+  // In general case circle event is made of the three consecutive sites
+  // that form two bisectors in the beach line data structure.
+  // Let circle event sites be A, B, C, two bisectors that define
+  // circle event are (A, B), (B, C). During circle event processing
+  // we remove (A, B), (B, C) and insert (A, C). As beach line comparison
+  // works correctly only if one of the nodes is a new one we remove
+  // (B, C) bisector and change (A, B) bisector to the (A, C). That's
+  // why we use const_cast there and take all the responsibility that
+  // map data structure keeps correct ordering.
+  template <typename OUTPUT>
+  void process_circle_event(OUTPUT *output) {
+    // Get the topmost circle event.
+    const event_type &e = circle_events_.top();
+    const circle_event_type &circle_event = e.first;
+    beach_line_iterator it_first = e.second;
+    beach_line_iterator it_last = it_first;
+
+    // Get the C site.
+    site_event_type site3 = it_first->first.right_site();
+
+    // Get the half-edge corresponding to the second bisector - (B, C).
+    edge_type *bisector2 = it_first->second.edge();
+
+    // Get the half-edge corresponding to the first bisector - (A, B).
+    --it_first;
+    edge_type *bisector1 = it_first->second.edge();
+
+    // Get the A site.
+    site_event_type site1 = it_first->first.left_site();
+
+    if (!site1.is_segment() && site3.is_segment() &&
+        site3.point1(true) == site1.point0()) {
+      site3.inverse();
+    }
+
+    // Change the (A, B) bisector node to the (A, C) bisector node.
+    const_cast<key_type &>(it_first->first).right_site(site3);
+
+    // Insert the new bisector into the beach line.
+    it_first->second.edge(output->builder()->insert_new_edge(
+        site1, site3, circle_event, bisector1, bisector2).first);
+
+    // Remove the (B, C) bisector node from the beach line.
+    beach_line_.erase(it_last);
+    it_last = it_first;
+
+    // Pop the topmost circle event from the event queue.
+    circle_events_.pop();
+
+    // Check new triplets formed by the neighboring arcs
+    // to the left for potential circle events.
+    if (it_first != beach_line_.begin()) {
+      deactivate_circle_event(it_first->second);
+      --it_first;
+      const site_event_type &site_l1 = it_first->first.left_site();
+      activate_circle_event(site_l1, site1, site3, it_last);
+    }
+
+    // Check the new triplet formed by the neighboring arcs
+    // to the right for potential circle events.
+    ++it_last;
+    if (it_last != beach_line_.end()) {
+      deactivate_circle_event(it_last->second);
+      const site_event_type &site_r1 = it_last->first.right_site();
+      activate_circle_event(site1, site3, site_r1, it_last);
+    }
+  }
+
+  // Insert new nodes into the beach line. Update the output.
+  template <typename OUTPUT>
+  beach_line_iterator insert_new_arc(
+      const site_event_type &site_arc1, const site_event_type &site_arc2,
+      const site_event_type &site_event, beach_line_iterator position,
+      OUTPUT *output) {
+    // Create two new bisectors with opposite directions.
+    key_type new_left_node(site_arc1, site_event);
+    key_type new_right_node(site_event, site_arc2);
+
+    // Set correct orientation for the first site of the second node.
+    if (site_event.is_segment()) {
+      new_right_node.left_site().inverse();
+    }
+
+    // Update the output.
+    std::pair<edge_type*, edge_type*> edges =
+        output->builder()->insert_new_edge(site_arc2, site_event);
+    position = beach_line_.insert(position,
+        typename beach_line_type::value_type(
+            new_right_node, value_type(edges.second)));
+
+    if (site_event.is_segment()) {
+      // Update the beach line with temporary bisector, that will
+      // disappear after processing site event corresponding to the
+      // second endpoint of the segment site.
+      key_type new_node(site_event, site_event);
+      new_node.right_site().inverse();
+      position = beach_line_.insert(position,
+          typename beach_line_type::value_type(new_node, value_type(NULL)));
+
+      // Update the data structure that holds temporary bisectors.
+      end_points_.push(std::make_pair(site_event.point1(), position));
+    }
+
+    position = beach_line_.insert(position,
+        typename beach_line_type::value_type(
+            new_left_node, value_type(edges.first)));
+
+    return position;
+  }
+
+  // Add a new circle event to the event queue.
+  // bisector_node corresponds to the (site2, site3) bisector.
+  void activate_circle_event(const site_event_type &site1,
+                             const site_event_type &site2,
+                             const site_event_type &site3,
+                             beach_line_iterator bisector_node) {
+    circle_event_type c_event;
+    // Check if the three input sites create a circle event.
+    if (circle_formation_predicate_(site1, site2, site3, c_event)) {
+      // Add the new circle event to the circle events queue.
+      // Update bisector's circle event iterator to point to the
+      // new circle event in the circle event queue.
+      event_type &e = circle_events_.push(
+          std::pair<circle_event_type, beach_line_iterator>(
+              c_event, bisector_node));
+      bisector_node->second.circle_event(&e.first);
+    }
+  }
+
+private:
+  point_comparison_predicate point_comparison_;
+  struct end_point_comparison {
+    bool operator() (const end_point_type &end1,
+                     const end_point_type &end2) const {
+      return point_comparison(end2.first, end1.first);
+    }
+    point_comparison_predicate point_comparison;
+  };
+
+  std::vector<site_event_type> site_events_;
+  site_event_iterator_type site_event_iterator_;
+  std::priority_queue< end_point_type, std::vector<end_point_type>,
+                       end_point_comparison > end_points_;
+  circle_event_queue_type circle_events_;
+  beach_line_type beach_line_;
+  circle_formation_predicate_type circle_formation_predicate_;
+
+  //Disallow copy constructor and operator=
+  voronoi_builder(const voronoi_builder&);
+  void operator=(const voronoi_builder&);
+};
+
+typedef voronoi_builder<detail::int32> default_voronoi_builder;
+}  // polygon
+}  // boost
+
+#endif  // BOOST_POLYGON_VORONOI_BUILDER
Added: trunk/boost/polygon/voronoi_diagram.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/voronoi_diagram.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,650 @@
+// Boost.Polygon library voronoi_diagram.hpp header file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POLYGON_VORONOI_DIAGRAM
+#define BOOST_POLYGON_VORONOI_DIAGRAM
+
+#include <vector>
+
+#include "detail/voronoi_ctypes.hpp"
+#include "detail/voronoi_structures.hpp"
+
+namespace boost {
+namespace polygon {
+
+// Forward declarations.
+template <typename T>
+class voronoi_edge;
+
+// Represents Voronoi cell.
+// Data members:
+//   1) pointer to the incident edge;
+//   2) site inside cell;
+//   3) data associated with a cell.
+// Cell may contain point or segment site inside.
+template <typename T>
+class voronoi_cell {
+public:
+  typedef T coordinate_type;
+  typedef detail::point_2d<coordinate_type> point_type;
+  typedef voronoi_edge<coordinate_type> voronoi_edge_type;
+
+  voronoi_cell(const point_type &p1, voronoi_edge_type *edge) :
+      point0_(p1),
+      point1_(p1),
+      incident_edge_(edge),
+      data_(NULL) {}
+
+  voronoi_cell(const point_type &p1,
+               const point_type &p2,
+               voronoi_edge_type *edge) :
+      point0_(p1),
+      point1_(p2),
+      incident_edge_(edge),
+      data_(NULL) {}
+
+  // Returns true if the cell contains point site, false else.
+  bool contains_point() const { return point0_ == point1_; }
+
+  // Returns true if the cell contains segment site, false else.
+  bool contains_segment() const { return point0_ != point1_; }
+
+  // Degenerate cells don't have any incident edges.
+  bool is_degenerate() const { return incident_edge_ == NULL; }
+
+  // Returns site point in case cell contains point site,
+  // the first endpoint of the segment site else.
+  const point_type &point0() const { return point0_; }
+
+  // Returns site point in case cell contains point site,
+  // the second endpoint of the segment site else.
+  const point_type &point1() const { return point1_; }
+
+  voronoi_edge_type *incident_edge() { return incident_edge_; }
+  const voronoi_edge_type *incident_edge() const { return incident_edge_; }
+  void incident_edge(voronoi_edge_type *e) { incident_edge_ = e; }
+
+#ifndef NO_VORONOI_CELL_DATA
+  void *data() const { return data_; }
+  void data(void *d) const { data_ = d; }
+#endif
+
+private:
+  point_type point0_;
+  point_type point1_;
+  voronoi_edge_type *incident_edge_;
+#ifndef NO_VORONOI_CELL_DATA
+  mutable void *data_;
+#endif
+};
+
+// Represents Voronoi vertex.
+// Data members:
+//   1) vertex point itself;
+//   2) pointer to the incident edge;
+//   3) data associated with vertex.
+template <typename T>
+class voronoi_vertex {
+public:
+  typedef T coordinate_type;
+  typedef detail::point_2d<T> point_type;
+  typedef voronoi_edge<coordinate_type> voronoi_edge_type;
+
+  voronoi_vertex(const point_type &vertex, voronoi_edge_type *edge) :
+      vertex_(vertex),
+      incident_edge_(edge),
+      data_(NULL) {}
+
+  const point_type &vertex() const { return vertex_; }
+
+  bool is_degenerate() const { return incident_edge_ == NULL; }
+
+  voronoi_edge_type *incident_edge() { return incident_edge_; }
+  const voronoi_edge_type *incident_edge() const { return incident_edge_; }
+  void incident_edge(voronoi_edge_type *e) { incident_edge_ = e; }
+
+#ifndef NO_VORONOI_VERTEX_DATA
+  void *data() const { return data_; }
+  void data(void *d) const { data_ = d; }
+#endif
+
+private:
+  point_type vertex_;
+  voronoi_edge_type *incident_edge_;
+#ifndef NO_VORONOI_VERTEX_DATA
+  mutable void *data_;
+#endif
+};
+
+// Half-edge data structure. Represents Voronoi edge.
+// Data members:
+//   1) pointer to the corresponding cell;
+//   2) pointer to the vertex that is the starting
+//      point of the half-edge;
+//   3) pointer to the twin edge;
+//   4) pointer to the CCW next edge;
+//   5) pointer to the CCW prev edge;
+//   6) pointer to data associated with edge.
+template <typename T>
+class voronoi_edge {
+public:
+  typedef T coordinate_type;
+  typedef voronoi_cell<coordinate_type> voronoi_cell_type;
+  typedef voronoi_vertex<coordinate_type> voronoi_vertex_type;
+  typedef voronoi_edge<coordinate_type> voronoi_edge_type;
+
+  voronoi_edge() :
+      cell_(NULL),
+      vertex_(NULL),
+      twin_(NULL),
+      next_(NULL),
+      prev_(NULL),
+      data_(NULL) {}
+
+  voronoi_cell_type *cell() { return cell_; }
+  const voronoi_cell_type *cell() const { return cell_; }
+  void cell(voronoi_cell_type *c) { cell_ = c; }
+
+  voronoi_vertex_type *vertex0() { return vertex_; }
+  const voronoi_vertex_type *vertex0() const { return vertex_; }
+  void vertex0(voronoi_vertex_type *v) { vertex_ = v; }
+
+  voronoi_vertex_type *vertex1() { return twin_->vertex0(); }
+  const voronoi_vertex_type *vertex1() const { return twin_->vertex0(); }
+  void vertex1(voronoi_vertex_type *v) { twin_->vertex0(v); }
+
+  voronoi_edge_type *twin() { return twin_; }
+  const voronoi_edge_type *twin() const { return twin_; }
+  void twin(voronoi_edge_type *e) { twin_ = e; }
+
+  voronoi_edge_type *next() { return next_; }
+  const voronoi_edge_type *next() const { return next_; }
+  void next(voronoi_edge_type *e) { next_ = e; }
+
+  voronoi_edge_type *prev() { return prev_; }
+  const voronoi_edge_type *prev() const { return prev_; }
+  void prev(voronoi_edge_type *e) { prev_ = e; }
+
+#ifndef NO_VORONOI_EDGE_DATA
+  void *data() const { return data_; }
+  void data(void *d) const { data_ = d; }
+#endif
+
+  // Returns a pointer to the rotation next edge
+  // over the starting point of the half-edge.
+  voronoi_edge_type *rot_next() {
+    return (vertex_) ? prev_->twin() : NULL;
+  }
+  const voronoi_edge_type *rot_next() const {
+    return (vertex_) ? prev_->twin() : NULL;
+  }
+
+  // Returns a pointer to the rotation prev edge
+  // over the starting point of the half-edge.
+  voronoi_edge_type *rot_prev() {
+    return (vertex_) ? twin_->next() : NULL;
+  }
+  const voronoi_edge_type *rot_prev() const {
+    return (vertex_) ? twin_->next() : NULL;
+  }
+
+  // Returns true if the edge is finite (segment, parabolic arc).
+  // Returns false if the edge is infinite (ray, line).
+  bool is_finite() const { return vertex0() && vertex1(); }
+
+  // Returns true if the edge is linear (segment, ray, line).
+  // Returns false if the edge is curved (parabolic arc).
+  bool is_linear() const {
+    if (!is_primary())
+      return true;
+    return !(cell()->contains_segment() ^ twin()->cell()->contains_segment());
+  }
+
+  // Returns true if the edge is curved (parabolic arc).
+  // Returns false if the edge is linear (segment, ray, line).
+  bool is_curved() const {
+    if (!is_primary())
+      return false;
+    return (cell()->contains_segment() ^ twin()->cell()->contains_segment());
+  }
+
+  // Returns false if edge goes through the endpoint of the segment.
+  // Returns true else.
+  bool is_primary() const {
+    bool flag1 = cell_->contains_segment();
+    bool flag2 = twin_->cell()->contains_segment();
+    if (flag1 && !flag2) {
+      return cell_->point0() != twin_->cell()->point0() &&
+             cell_->point1() != twin_->cell()->point0();
+    }
+    if (!flag1 && flag2) {
+      return twin_->cell()->point0() != cell_->point0() &&
+             twin_->cell()->point1() != cell_->point0();
+    }
+    return true;
+  }
+
+private:
+  voronoi_cell_type *cell_;
+  voronoi_vertex_type *vertex_;
+  voronoi_edge_type *twin_;
+  voronoi_edge_type *next_;
+  voronoi_edge_type *prev_;
+#ifndef NO_VORONOI_EDGE_DATA
+  mutable void *data_;
+#endif
+};
+
+template <typename T>
+struct voronoi_diagram_traits {
+  typedef T coordinate_type;
+  typedef struct {
+    template <typename CT>
+    coordinate_type operator()(const CT& value) {
+      return static_cast<coordinate_type>(value);
+    }
+  } ctype_converter_type;
+  typedef detail::point_2d<coordinate_type> point_type;
+  typedef voronoi_cell<coordinate_type> cell_type;
+  typedef voronoi_vertex<coordinate_type> vertex_type;
+  typedef voronoi_edge<coordinate_type> edge_type;
+  typedef class {
+  public:
+    enum { ULPS = 128 };
+    bool operator()(const point_type &v1, const point_type &v2) const {
+      return (ulp_cmp(v1.x(), v2.x(), ULPS) ==
+              detail::ulp_comparison<T>::EQUAL) &&
+             (ulp_cmp(v1.y(), v2.y(), ULPS) ==
+              detail::ulp_comparison<T>::EQUAL);
+    }
+  private:
+    typename detail::ulp_comparison<T> ulp_cmp;
+  } vertex_equality_predicate_type;
+};
+
+// Voronoi output data structure.
+// CCW ordering is used on the faces perimeter and around the vertices.
+template <typename T, typename TRAITS = voronoi_diagram_traits<T> >
+class voronoi_diagram {
+public:
+  typedef typename TRAITS::coordinate_type coordinate_type;
+  typedef typename TRAITS::point_type point_type;
+  typedef typename TRAITS::cell_type cell_type;
+  typedef typename TRAITS::vertex_type vertex_type;
+  typedef typename TRAITS::edge_type edge_type;
+
+  typedef std::vector<cell_type> cell_container_type;
+  typedef typename cell_container_type::iterator cell_iterator;
+  typedef typename cell_container_type::const_iterator const_cell_iterator;
+
+  typedef std::vector<vertex_type> vertex_container_type;
+  typedef typename vertex_container_type::iterator vertex_iterator;
+  typedef typename vertex_container_type::const_iterator const_vertex_iterator;
+
+  typedef std::vector<edge_type> edge_container_type;
+  typedef typename edge_container_type::iterator edge_iterator;
+  typedef typename edge_container_type::const_iterator const_edge_iterator;
+
+  // This builder class is mainly used to hide from the user methods that
+  // construct the Voronoi diagram.
+  class voronoi_diagram_builder {
+  public:
+    void vd(voronoi_diagram *vd) {
+      vd_ = vd;
+    }
+
+    bool done() {
+      return vd_ == NULL;
+    }
+
+    void reserve(int num_sites) {
+      vd_->reserve(num_sites);
+    }
+
+    template <typename SEvent>
+    void process_single_site(const SEvent &site) {
+      vd_->process_single_site(site);
+    }
+
+    template <typename SEvent>
+    std::pair<void*, void*> insert_new_edge(
+        const SEvent &site1, const SEvent &site2) {
+      return vd_->insert_new_edge(site1, site2);
+    }
+
+    template <typename SEvent, typename CEvent>
+    std::pair<void *, void *> insert_new_edge(
+        const SEvent &site1, const SEvent &site3, const CEvent &circle,
+        void *data12, void *data23) {
+      return vd_->insert_new_edge(site1, site3, circle, data12, data23);
+    }
+
+    void build() {
+      vd_->build();
+      vd_ = NULL;
+    }
+
+  private:
+    voronoi_diagram *vd_;
+  };
+
+  voronoi_diagram() {
+    builder_.vd(&(*this));
+  }
+
+  void clear() {
+    cells_.clear();
+    vertices_.clear();
+    edges_.clear();
+    builder_.vd(&(*this));
+  }
+
+  const cell_container_type &cells() const {
+    return cells_;
+  }
+
+  const vertex_container_type &vertices() const {
+    return vertices_;
+  }
+
+  const edge_container_type &edges() const {
+    return edges_;
+  }
+
+  unsigned int num_cells() const {
+    return cells_.size();
+  }
+
+  unsigned int num_edges() const {
+    return edges_.size() >> 1;
+  }
+
+  unsigned int num_vertices() const {
+    return vertices_.size();
+  }
+
+  voronoi_diagram_builder *builder() {
+    if (builder_.done()) {
+      return NULL;
+    } else {
+      return &builder_;
+    }
+  }
+
+private:
+  typedef typename TRAITS::ctype_converter_type ctype_converter_type;
+  typedef typename TRAITS::vertex_equality_predicate_type
+    vertex_equality_predicate_type;
+
+  friend class voronoi_diagram_builder;
+
+  void reserve(int num_sites) {
+    cells_.reserve(num_sites);
+    vertices_.reserve(num_sites << 1);
+    edges_.reserve((num_sites << 2) + (num_sites << 1));
+  }
+
+  // Update the Voronoi output in case of a single point input.
+  template <typename SEvent>
+  void process_single_site(const SEvent &site) {
+    // Update cell records.
+    point_type p = prepare_point(site.point0());
+    cells_.push_back(cell_type(p, NULL));
+  }
+
+  // Insert a new half-edge into the output data structure.
+  // Takes as input left and right sites that form a new bisector.
+  // Returns a pair of pointers to a new half-edges.
+  template <typename SEvent>
+  std::pair<void*, void*> insert_new_edge(
+      const SEvent &site1, const SEvent &site2) {
+    // Get sites' indexes.
+    int site_index1 = site1.index();
+    int site_index2 = site2.index();
+
+    // Create a new half-edge that belongs to the first site.
+    edges_.push_back(edge_type());
+    edge_type &edge1 = edges_.back();
+
+    // Create a new half-edge that belongs to the second site.
+    edges_.push_back(edge_type());
+    edge_type &edge2 = edges_.back();
+
+    // Add the initial cell during the first edge insertion.
+    if (cells_.empty()) {
+      process_single_site(site1);
+    }
+
+    // The second site represents a new site during site event
+    // processing. Add a new cell to the cell records.
+    cells_.push_back(cell_type(prepare_point(site2.point0()),
+                               prepare_point(site2.point1()),
+                               NULL));
+
+    // Set up pointers to cells.
+    edge1.cell(&cells_[site_index1]);
+    edge2.cell(&cells_[site_index2]);
+
+    // Set up twin pointers.
+    edge1.twin(&edge2);
+    edge2.twin(&edge1);
+
+    // Return a pointer to the new half-edge.
+    return std::make_pair(&edge1, &edge2);
+  }
+
+  // Insert a new half-edge into the output data structure with the
+  // start at the point where two previously added half-edges intersect.
+  // Takes as input two sites that create a new bisector, circle event
+  // that corresponds to the intersection point of the two old half-edges,
+  // pointers to those half-edges. Half-edges' direction goes out of the
+  // new Voronoi vertex point. Returns a pair of pointers to a new half-edges.
+  template <typename SEvent, typename CEvent>
+  std::pair<void *, void *> insert_new_edge(
+      const SEvent &site1, const SEvent &site3, const CEvent &circle,
+      void *data12, void *data23) {
+    edge_type *edge12 = static_cast<edge_type*>(data12);
+    edge_type *edge23 = static_cast<edge_type*>(data23);
+
+    // Add a new Voronoi vertex.
+    vertices_.push_back(vertex_type(prepare_point(circle), NULL));
+    vertex_type &new_vertex = vertices_.back();
+
+    // Update vertex pointers of the old edges.
+    edge12->vertex0(&new_vertex);
+    edge23->vertex0(&new_vertex);
+
+    // Add a new half-edge.
+    edges_.push_back(edge_type());
+    edge_type &new_edge1 = edges_.back();
+    new_edge1.cell(&cells_[site1.index()]);
+
+    // Add a new half-edge.
+    edges_.push_back(edge_type());
+    edge_type &new_edge2 = edges_.back();
+    new_edge2.cell(&cells_[site3.index()]);
+
+    // Update twin pointers.
+    new_edge1.twin(&new_edge2);
+    new_edge2.twin(&new_edge1);
+
+    // Update vertex pointer.
+    new_edge2.vertex0(&new_vertex);
+
+    // Update Voronoi prev/next pointers.
+    edge12->prev(&new_edge1);
+    new_edge1.next(edge12);
+    edge12->twin()->next(edge23);
+    edge23->prev(edge12->twin());
+    edge23->twin()->next(&new_edge2);
+    new_edge2.prev(edge23->twin());
+
+    // Return a pointer to the new half-edge.
+    return std::make_pair(&new_edge1, &new_edge2);
+  }
+
+  void build() {
+    // Remove degenerate edges.
+    edge_iterator last_edge = edges_.begin();
+    for (edge_iterator it = edges_.begin(); it != edges_.end(); it += 2) {
+      const vertex_type *v1 = it->vertex0();
+      const vertex_type *v2 = it->vertex1();
+      if (v1 && v2 && vertex_equality_predicate_(v1->vertex(), v2->vertex())) {
+        remove_edge(&(*it));
+      } else {
+        if (it != last_edge) {
+          edge_type *e1 = &(*last_edge = *it);
+          edge_type *e2 = &(*(last_edge + 1) = *(it + 1));
+          e1->twin(e2);
+          e2->twin(e1);
+          if (e1->prev()) {
+            e1->prev()->next(e1); 
+            e2->next()->prev(e2);
+          }
+          if (e2->prev()) {
+            e1->next()->prev(e1);
+            e2->prev()->next(e2);
+          }
+        }
+        last_edge += 2;
+      }
+    }
+    edges_.erase(last_edge, edges_.end());
+
+    // Set up incident edge pointers for cells and vertices.
+    for (edge_iterator it = edges_.begin(); it != edges_.end(); ++it) {
+      it->cell()->incident_edge(&(*it));
+      if (it->vertex0()) {
+        it->vertex0()->incident_edge(&(*it));
+      }
+    }
+
+    // Remove degenerate vertices.
+    vertex_iterator last_vertex = vertices_.begin();
+    for (vertex_iterator it = vertices_.begin(); it != vertices_.end(); ++it) {
+      if (it->incident_edge()) {
+        if (it != last_vertex) {
+          *last_vertex = *it;
+          vertex_type *v = &(*last_vertex);
+          edge_type *e = v->incident_edge();
+          do {
+            e->vertex0(v);
+            e = e->rot_next();
+          } while (e != v->incident_edge());
+        }
+        ++last_vertex;
+      }
+    }
+    vertices_.erase(last_vertex, vertices_.end());
+
+    // Set up next/prev pointers for infinite edges.
+    if (vertices_.empty()) {
+      if (!edges_.empty()) {
+        // Update prev/next pointers for the line edges.
+        edge_iterator edge_it = edges_.begin();
+        edge_type *edge1 = &(*edge_it);
+        edge1->next(edge1);
+        edge1->prev(edge1);
+        ++edge_it;
+        edge1 = &(*edge_it);
+        ++edge_it;
+
+        while (edge_it != edges_.end()) {
+          edge_type *edge2 = &(*edge_it);
+          ++edge_it;
+
+          edge1->next(edge2);
+          edge1->prev(edge2);
+          edge2->next(edge1);
+          edge2->prev(edge1);
+
+          edge1 = &(*edge_it);
+          ++edge_it;
+        }
+
+        edge1->next(edge1);
+        edge1->prev(edge1);
+      }
+    } else {
+      // Update prev/next pointers for the ray edges.
+      for (cell_iterator cell_it = cells_.begin();
+         cell_it != cells_.end(); ++cell_it) {
+        if (cell_it->is_degenerate())
+          continue;
+        // Move to the previous edge while
+        // it is possible in the CW direction.
+        edge_type *left_edge = cell_it->incident_edge();
+        while (left_edge->prev() != NULL) {
+          left_edge = left_edge->prev();
+          // Terminate if this is not a boundary cell.
+          if (left_edge == cell_it->incident_edge())
+            break;
+        }
+
+        if (left_edge->prev() != NULL)
+          continue;
+
+        edge_type *right_edge = cell_it->incident_edge();
+        while (right_edge->next() != NULL)
+          right_edge = right_edge->next();
+        left_edge->prev(right_edge);
+        right_edge->next(left_edge);
+      }
+    }
+  }
+
+  template <typename P>
+  point_type prepare_point(const P& p) {
+    coordinate_type nx = convert_(p.x());
+    coordinate_type ny = convert_(p.y());
+    return point_type(nx, ny);
+  }
+
+  // Remove degenerate edge.
+  void remove_edge(edge_type *edge) {
+    // Update the endpoints of the incident edges to the second vertex.
+    vertex_type *vertex = edge->vertex0();
+    edge_type *updated_edge = edge->twin()->rot_next();
+    while (updated_edge != edge->twin()) {
+      updated_edge->vertex0(vertex);
+      updated_edge = updated_edge->rot_next();
+    }
+
+    edge_type *edge1 = edge;
+    edge_type *edge2 = edge->twin();
+
+    edge_type *edge1_rot_prev = edge1->rot_prev();
+    edge_type *edge1_rot_next = edge1->rot_next();
+
+    edge_type *edge2_rot_prev = edge2->rot_prev();
+    edge_type *edge2_rot_next = edge2->rot_next();
+
+    // Update prev/next pointers for the incident edges.
+    edge1_rot_next->twin()->next(edge2_rot_prev);
+    edge2_rot_prev->prev(edge1_rot_next->twin());
+    edge1_rot_prev->prev(edge2_rot_next->twin());
+    edge2_rot_next->twin()->next(edge1_rot_prev);
+  }
+
+  cell_container_type cells_;
+  vertex_container_type vertices_;
+  edge_container_type edges_;
+
+  voronoi_diagram_builder builder_;
+  ctype_converter_type convert_;
+  vertex_equality_predicate_type vertex_equality_predicate_;
+
+  // Disallow copy constructor and operator=
+  voronoi_diagram(const voronoi_diagram&);
+  void operator=(const voronoi_diagram&);
+};
+}  // polygon
+}  // boost
+
+#endif  // BOOST_POLYGON_VORONOI_DIAGRAM
Added: trunk/boost/polygon/voronoi_utils.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/polygon/voronoi_utils.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,479 @@
+// Boost.Polygon library voronoi_utils.hpp header file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POLYGON_VORONOI_UTILS
+#define BOOST_POLYGON_VORONOI_UTILS
+
+#include <cmath>
+#include <stack>
+#include <vector>
+
+#include "voronoi_diagram.hpp"
+
+namespace boost {
+namespace polygon {
+
+// Bounding rectangle data structure. Contains coordinates
+// of the bottom left and upper right corners of rectangle.
+template <typename T>
+class bounding_rectangle {
+public:
+  typedef T coordinate_type;
+
+  bounding_rectangle() : x_min_(1), x_max_(0) {}
+
+  bounding_rectangle(coordinate_type x1, coordinate_type y1,
+                     coordinate_type x2, coordinate_type y2) {
+    x_min_ = (std::min)(x1, x2);
+    y_min_ = (std::min)(y1, y2);
+    x_max_ = (std::max)(x1, x2);
+    y_max_ = (std::max)(y1, y2);
+  }
+
+  // Update bounding rectangle.
+  void update(coordinate_type x, coordinate_type y) {
+    if (x_min_ > x_max_) {
+      x_min_ = x_max_ = x;
+      y_min_ = y_max_ = y;
+    } else {
+      x_min_ = (std::min)(x_min_, x);
+      y_min_ = (std::min)(y_min_, y);
+      x_max_ = (std::max)(x_max_, x);
+      y_max_ = (std::max)(y_max_, y);
+    }
+  }
+
+  bool is_empty() const {
+    return x_min_ > x_max_;
+  }
+
+  void clear() {
+    x_min_ = 1;
+    x_max_ = 0;
+  }
+
+  bool contains(coordinate_type x, coordinate_type y) const {
+    return x > x_min_ && x < x_max_ && y > y_min_ && y < y_max_;
+  }
+
+  // Return the x-coordinate of the bottom left point of the rectangle.
+  coordinate_type x_min() const {
+    return x_min_;
+  }
+
+  // Return the y-coordinate of the bottom left point of the rectangle.
+  coordinate_type y_min() const {
+    return y_min_;
+  }
+
+  // Return the x-coordinate of the upper right point of the rectangle.
+  coordinate_type x_max() const {
+    return x_max_;
+  }
+
+  // Return the y-coordinate of the upper right point of the rectangle.
+  coordinate_type y_max() const {
+    return y_max_;
+  }
+
+private:
+  coordinate_type x_min_;
+  coordinate_type y_min_;
+  coordinate_type x_max_;
+  coordinate_type y_max_;
+};
+
+template <typename fpt>
+struct voronoi_utils_traits {
+  typedef fpt coordinate_type;
+  typedef detail::point_2d<coordinate_type> point_type;
+  typedef std::vector<point_type> point_set_type;
+  typedef bounding_rectangle<coordinate_type> brect_type;
+  typedef struct {
+    template <typename CT>
+      coordinate_type operator()(const CT& value) const {
+        return static_cast<coordinate_type>(value);
+    }
+  } ctype_converter_type;
+};
+
+// Voronoi output post-processing tools.
+template <typename T, typename TRAITS = voronoi_utils_traits<T> >
+class voronoi_utils {
+public:
+  typedef typename TRAITS::coordinate_type coordinate_type;
+  typedef typename TRAITS::point_type point_type;
+  typedef typename TRAITS::point_set_type point_set_type;
+  typedef typename TRAITS::brect_type brect_type;
+
+  // Get scaled by a factor bounding rectangle.
+  template <typename CT>
+  static brect_type scale(const bounding_rectangle<CT> &brect, 
+      coordinate_type factor) {
+    coordinate_type x_len = to_fpt(brect.x_max()) - to_fpt(brect.x_min());
+    coordinate_type y_len = to_fpt(brect.y_max()) - to_fpt(brect.y_min());
+    coordinate_type x_mid = to_fpt(brect.x_max()) + to_fpt(brect.x_min());
+    coordinate_type y_mid = to_fpt(brect.y_max()) + to_fpt(brect.y_min());
+    x_mid *= to_fpt(0.5);
+    y_mid *= to_fpt(0.5);
+    coordinate_type offset = (std::max)(x_len, y_len) * factor * to_fpt(0.5);
+    brect_type new_brect(x_mid - offset, y_mid - offset,
+                         x_mid + offset, y_mid + offset);
+    return new_brect;
+  }
+
+  // Discretizes finite Voronoi edge.
+  // Discretization absolute error is defined by max_error value.
+  template <typename CT>
+  static void discretize(const voronoi_edge<CT> &edge, 
+      coordinate_type max_error, point_set_type &discretization) {
+    // Don't process infinite edges.
+    if (!edge.is_finite())
+      return;
+
+    // Retrieve the cell to the left of the current edge.
+    const typename voronoi_edge<CT>::voronoi_cell_type *cell1 = edge.cell();
+    // Retrieve the cell to the right of the current edge.
+    const typename voronoi_edge<CT>::voronoi_cell_type *cell2 =
+        edge.twin()->cell();
+
+    discretization.push_back(get_point(edge.vertex0()->vertex()));
+    discretization.push_back(get_point(edge.vertex1()->vertex()));
+    if (edge.is_curved()) {
+      bool flag = cell1->contains_segment();
+      // point1 - site point;
+      point_type point1 = flag ?
+          get_point(cell2->point0()) : get_point(cell1->point0());
+      // point2 - start-point of the segment site;
+      point_type point2 = flag ?
+          get_point(cell1->point0()) : get_point(cell2->point0());
+      // point3 - endpoint of the segment site;
+      point_type point3 = flag ?
+          get_point(cell1->point1()) : get_point(cell2->point1());
+      fill_intermediate_points(
+          point1, point2, point3, max_error, discretization);
+    }
+  }
+
+  // Clip a linear Voronoi edge with a given rectangle.
+  template <typename CT>
+  static void clip(const voronoi_edge<CT> &edge,
+      const brect_type &brect, point_set_type &clipped_edge) {
+    // Don't process curved edges.
+    if (edge.is_curved())
+      return;
+
+    if (edge.is_finite()) {
+      clip(edge.vertex0()->vertex(), edge.vertex1()->vertex(),
+          brect, clipped_edge);
+    } else {
+      const typename voronoi_edge<CT>::voronoi_cell_type *cell1 = edge.cell();
+      const typename voronoi_edge<CT>::voronoi_cell_type *cell2 =
+          edge.twin()->cell();
+      point_type point1 = get_point(cell1->point0());
+      point_type point2 = get_point(cell2->point0());
+      if (point1 == point2) {
+        if (cell1->contains_segment())
+          point1 = get_point(cell1->point1());
+        else
+          point2 = get_point(cell2->point1());
+      }
+
+      if (edge.vertex0()) {
+        // Ray edge.
+        point_type origin = get_point(edge.vertex0()->vertex());
+        point_type direction(point1.y() - point2.y(), point2.x() - point1.x());
+        if (brect.contains(origin.x(), origin.y()))
+          clipped_edge.push_back(origin);
+        intersect(origin, direction, RAY, brect, clipped_edge);
+      } else if (edge.vertex1()) {
+        // Ray edge.
+        point_type origin = get_point(edge.vertex1()->vertex());
+        point_type direction(point2.y() - point1.y(), point1.x() - point2.x());
+        if (brect.contains(origin.x(), origin.y()))
+          clipped_edge.push_back(origin);
+        intersect(origin, direction, RAY, brect, clipped_edge);
+        // Keep correct ordering.
+        (std::reverse)(clipped_edge.begin(), clipped_edge.end());
+      } else if (cell1->contains_point() && cell2->contains_point()) {
+        // Primary line edge.
+        point_type origin((point1.x() + point2.x()) * 0.5, (point1.y() + point2.y()) * 0.5);
+        point_type direction(point1.y() - point2.y(), point2.x() - point1.x());
+        intersect(origin, direction, LINE, brect, clipped_edge);
+      } else {
+        point_type origin = cell1->contains_point() ? point1 : point2;
+        point_type direction(point1.y() - point2.y(), point2.x() - point1.x());
+        intersect(origin, direction, LINE, brect, clipped_edge);
+      }
+    }
+  }
+
+  // Clip an edge with the given rectangle.
+  template <typename PointType>
+  static void clip(const PointType &p1, const PointType &p2,
+      const brect_type &brect, point_set_type &clipped_edge) {
+    point_type start = get_point(p1);
+    point_type end = get_point(p2);
+    point_type direction(end.x() - start.x(), end.y() - start.y());
+    if (brect.contains(start.x(), start.y()))
+      clipped_edge.push_back(start);
+    if (p1 != p2)
+      intersect(start, direction, SEGMENT, brect, clipped_edge);
+    if (brect.contains(end.x(), end.y()))
+      clipped_edge.push_back(end);
+  }
+
+private:
+  typedef typename TRAITS::ctype_converter_type ctype_converter_type;
+
+  voronoi_utils();
+
+  // There are three different types of linear primitive:
+  //   1) SEGMENT - has two finite endpoints;
+  //   2) RAY - has one finite and one infinite endpoint;
+  //   3) LINE - has two infinite endpoints.
+  enum EdgeType {
+    SEGMENT = 0,
+    RAY = 1,
+    LINE = 2
+  };
+
+  template <typename P>
+  static point_type get_point(const P &point) {
+    coordinate_type x = to_fpt(point.x());
+    coordinate_type y = to_fpt(point.y());
+    return point_type(x, y);
+  }
+
+  static void intersect(
+      const point_type &origin, const point_type &direction,
+      EdgeType edge_type, const brect_type &brect,
+      point_set_type &clipped_edge) {
+    // Find the center of the rectangle.
+    coordinate_type center_x = (brect.x_min() + brect.x_max()) * to_fpt(0.5);
+    coordinate_type center_y = (brect.y_min() + brect.y_max()) * to_fpt(0.5);
+
+    // Find the half-diagonal vector of the rectangle.
+    coordinate_type len_x = brect.x_max() - center_x;
+    coordinate_type len_y = brect.y_max() - center_y;
+
+    // Find the vector between the origin and the center of the
+    // rectangle.
+    coordinate_type diff_x = origin.x() - center_x;
+    coordinate_type diff_y = origin.y() - center_y;
+
+    // Find the vector perpendicular to the direction vector.
+    coordinate_type perp_x = direction.y();
+    coordinate_type perp_y = -direction.x();
+
+    // Projection of the vector between the origin and the center of
+    // the rectangle on the line perpendicular to the direction vector.
+    coordinate_type lexpr = magnitude(perp_x * diff_x + perp_y * diff_y);
+
+    // Maximum projection among any of the half-diagonals of the
+    // rectangle on the line perpendicular to the direction vector.
+    coordinate_type rexpr =
+        magnitude(perp_x * len_x) + magnitude(perp_y * len_y);
+
+    // Intersection check. Compare projections.
+    if (lexpr > rexpr)
+      return;
+
+    // Intersection parameters. If fT[i]_used is true than:
+    // origin + fT[i] * direction = intersection point, i = 0 .. 1.
+    // For different edge types next fT values are acceptable:
+    // Segment: [0; 1];
+    // Ray: [0; infinity];
+    // Line: [-infinity; infinity].
+    bool fT0_used = false;
+    bool fT1_used = false;
+    coordinate_type fT0 = 0;
+    coordinate_type fT1 = 0;
+
+    // Check for the intersections with the lines
+    // going through the sides of the bounding rectangle.
+    clip_line(+direction.x(), -diff_x - len_x, fT0_used, fT1_used, fT0, fT1);
+    clip_line(-direction.x(), +diff_x - len_x, fT0_used, fT1_used, fT0, fT1);
+    clip_line(+direction.y(), -diff_y - len_y, fT0_used, fT1_used, fT0, fT1);
+    clip_line(-direction.y(), +diff_y - len_y, fT0_used, fT1_used, fT0, fT1);
+
+    // Update intersections vector.
+    if (fT0_used && check_extent(fT0, edge_type))
+      clipped_edge.push_back(point_type(
+          origin.x() + fT0 * direction.x(), origin.y() + fT0 * direction.y()));
+    if (fT1_used && fT0 != fT1 && check_extent(fT1, edge_type))
+      clipped_edge.push_back(point_type(
+          origin.x() + fT1 * direction.x(), origin.y() + fT1 * direction.y()));
+  }
+
+  // Find intermediate points of the parabola.
+  // Parabola is a locus of points equidistant from the point and segment
+  // sites. intermediate_points should contain two initial endpoints
+  // of the edge (Voronoi vertices). Intermediate points are inserted
+  // between the given two endpoints.
+  // Max_dist is the maximum distance allowed between parabola and line
+  // segments that discretize it.
+  static void fill_intermediate_points(
+      point_type point_site, point_type segment_site_start,
+      point_type segment_site_end, coordinate_type max_dist,
+      point_set_type &intermediate_points) {
+    // Apply the linear transformation to move start point of the
+    // segment to the point with coordinates (0, 0) and the direction
+    // of the segment to coincide the positive direction of the x-axis.
+    coordinate_type segm_vec_x =
+        segment_site_end.x() - segment_site_start.x();
+    coordinate_type segm_vec_y =
+        segment_site_end.y() - segment_site_start.y();
+    coordinate_type sqr_segment_length =
+        segm_vec_x * segm_vec_x + segm_vec_y * segm_vec_y;
+
+    // Compute x-coordinates of the endpoints of the edge
+    // in the transformed space.
+    coordinate_type projection_start = sqr_segment_length *
+        get_point_projection(
+            intermediate_points[0], segment_site_start, segment_site_end);
+    coordinate_type projection_end = sqr_segment_length *
+        get_point_projection(
+            intermediate_points[1], segment_site_start, segment_site_end);
+
+    // Compute parabola parameters in the transformed space.
+    // Parabola has next representation:
+    // f(x) = ((x-rot_x)^2 + rot_y^2) / (2.0*rot_y).
+    coordinate_type point_vec_x = point_site.x() - segment_site_start.x();
+    coordinate_type point_vec_y = point_site.y() - segment_site_start.y();
+    coordinate_type rot_x =
+        segm_vec_x * point_vec_x + segm_vec_y * point_vec_y;
+    coordinate_type rot_y =
+        segm_vec_x * point_vec_y - segm_vec_y * point_vec_x;
+
+    // Save the last point.
+    point_type last_point = intermediate_points[1];
+    intermediate_points.pop_back();
+
+    // Use stack to avoid recursion.
+    std::stack<coordinate_type> point_stack;
+    point_stack.push(projection_end);
+    coordinate_type cur_x = projection_start;
+    coordinate_type cur_y = parabola_y(cur_x, rot_x, rot_y);
+
+    // Adjust max_dist parameter in the transformed space.
+    max_dist *= max_dist * sqr_segment_length;
+
+    while (!point_stack.empty()) {
+      coordinate_type new_x = point_stack.top();
+      coordinate_type new_y = parabola_y(new_x, rot_x, rot_y);
+
+      // Compute coordinates of the point of the parabola that is
+      // furthest from the current line segment.
+      coordinate_type mid_x =
+          (new_y - cur_y) / (new_x - cur_x) * rot_y + rot_x;
+      coordinate_type mid_y = parabola_y(mid_x, rot_x, rot_y);
+
+      // Compute maximum distance between the given parabolic arc
+      // and line segment that discretize it.
+      coordinate_type dist = (new_y - cur_y) * (mid_x - cur_x) -
+          (new_x - cur_x) * (mid_y - cur_y);
+      dist = dist * dist / ((new_y - cur_y) * (new_y - cur_y) +
+          (new_x - cur_x) * (new_x - cur_x));
+      if (dist <= max_dist) {
+        // Distance between parabola and line segment is
+        // not greater than max_dist.
+        point_stack.pop();
+        coordinate_type inter_x = (segm_vec_x * new_x - segm_vec_y * new_y) /
+            sqr_segment_length + segment_site_start.x();
+        coordinate_type inter_y = (segm_vec_x * new_y + segm_vec_y * new_x) /
+            sqr_segment_length + segment_site_start.y();
+        intermediate_points.push_back(point_type(inter_x, inter_y));
+        cur_x = new_x;
+        cur_y = new_y;
+      } else {
+        point_stack.push(mid_x);
+      }
+    }
+
+    // Update last point.
+    intermediate_points.back() = last_point;
+  }
+
+  // Compute y(x) = ((x - a) * (x - a) + b * b) / (2 * b).
+  static coordinate_type parabola_y(
+      coordinate_type x, coordinate_type a, coordinate_type b) {
+    return ((x - a) * (x - a) + b * b) / (to_fpt(2.0) * b);
+  }
+
+  // Check whether extent is compatible with the edge type.
+  static bool check_extent(coordinate_type extent, EdgeType etype) {
+    switch (etype) {
+      case SEGMENT: return extent >= to_fpt(0.0) && extent <= to_fpt(1.0);
+      case RAY: return extent >= to_fpt(0.0);
+      case LINE: return true;
+    }
+    return true;
+  }
+
+  // Compute the absolute value.
+  static inline coordinate_type magnitude(coordinate_type value) {
+    return (value >= to_fpt(0.0)) ? value : -value;
+  }
+
+  // Find fT min and max values: fT = numer / denom.
+  static void clip_line(
+      coordinate_type denom, coordinate_type numer,
+      bool &fT0_used, bool &fT1_used,
+      coordinate_type &fT0, coordinate_type &fT1) {
+    if (denom > to_fpt(0.0)) {
+      if (fT1_used && numer > denom * fT1)
+        return;
+      if (!fT0_used || numer > denom * fT0) {
+        fT0_used = true;
+        fT0 = numer / denom;
+      }
+    } else if (denom < to_fpt(0.0)) {
+      if (fT0_used && numer > denom * fT0)
+        return;
+      if (!fT1_used || numer > denom * fT1) {
+        fT1_used = true;
+        fT1 = numer / denom;
+      }
+    }
+  }
+
+  // Get normalized length of the distance between:
+  //   1) point projection onto the segment;
+  //   2) start point of the segment.
+  // Return this length divided by the segment length.
+  // This is made to avoid sqrt computation during transformation from
+  // the initial space to the transformed one and vice versa.
+  // Assumption is made that projection of the point lies
+  // between the start-point and endpoint of the segment.
+  static coordinate_type get_point_projection(
+      const point_type &point,
+      const point_type &segment_start,
+      const point_type &segment_end) {
+    coordinate_type segment_vec_x = segment_end.x() - segment_start.x();
+    coordinate_type segment_vec_y = segment_end.y() - segment_start.y();
+    coordinate_type point_vec_x = point.x() - segment_start.x();
+    coordinate_type point_vec_y = point.y() - segment_start.y();
+    coordinate_type sqr_segment_length =
+        segment_vec_x * segment_vec_x + segment_vec_y * segment_vec_y;
+    coordinate_type vec_dot =
+        segment_vec_x * point_vec_x + segment_vec_y * point_vec_y;
+    return vec_dot / sqr_segment_length;
+  }
+
+  template <typename CT>
+  static coordinate_type to_fpt(const CT& value) {
+    static ctype_converter_type converter;
+    return converter(value);
+  }
+};
+}  // polygon
+}  // boost
+
+#endif  // BOOST_POLYGON_VORONOI_UTILS
Modified: trunk/libs/polygon/test/Jamfile.v2
==============================================================================
--- trunk/libs/polygon/test/Jamfile.v2	(original)
+++ trunk/libs/polygon/test/Jamfile.v2	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -13,10 +13,22 @@
     requirements
         <include>.
         <toolset>msvc:<asynch-exceptions>on
+        <library>/boost/test//boost_unit_test_framework
     ;
 
 test-suite polygon-unit
     :
-    [ run gtl_boost_unit_test.cpp ]
+        [ run polygon_segment_test.cpp ]
+        [ run gtl_boost_unit_test.cpp ]
     ;
 
+test-suite voronoi-unit
+    :
+        [ run voronoi_builder_test.cpp ]
+        [ run voronoi_ctypes_test.cpp ]
+        [ run voronoi_predicates_test.cpp ]
+        [ run voronoi_robust_fpt_test.cpp ]
+        [ run voronoi_structures_test.cpp ]
+    ;
+
+
Modified: trunk/libs/polygon/test/gtl_boost_unit_test.cpp
==============================================================================
--- trunk/libs/polygon/test/gtl_boost_unit_test.cpp	(original)
+++ trunk/libs/polygon/test/gtl_boost_unit_test.cpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -194,7 +194,7 @@
     return o << r.get(HORIZONTAL) << ' ' << r.get(VERTICAL);
   }
   template <class T>
-  std::ostream& operator << (std::ostream& o, const directed_line_segment_data<T>& r)
+  std::ostream& operator << (std::ostream& o, const segment_data<T>& r)
   {
     return o << r.get(LOW) << ' ' << r.get(HIGH);
   }
@@ -3649,15 +3649,15 @@
   {
     using namespace gtl;
     typedef point_data<int> Point;
-    typedef directed_line_segment_data<int> Dls;
+    typedef segment_data<int> Segment;
     Point pt1(0, 0);
     Point pt2(10, 10);
     Point pt3(20, 20);
     Point pt4(20, 0);
-    Dls dls1(pt1, pt2);
-    Dls dls2(pt1, pt3);
-    Dls dls3(pt1, pt4);
-    Dls dls4(pt2, pt1);
+    Segment dls1(pt1, pt2);
+    Segment dls2(pt1, pt3);
+    Segment dls3(pt1, pt4);
+    Segment dls4(pt2, pt1);
     bool b1 = equivalence(dls1, dls1);
     bool b2 = equivalence(dls1, dls2);
     bool b3 = equivalence(dls1, dls3);
@@ -3704,10 +3704,9 @@
     std::cout << euclidean_distance(dls1, Point(5, 6)) << std::endl;
     std::cout << euclidean_distance(dls1, Point(5, 3)) << std::endl;
     std::cout << euclidean_distance(dls1, dls3) << std::endl;
-    std::cout << euclidean_distance(dls1, directed_line_segment_data<int>(Point(2, 0), Point(3, 0))) << std::endl;
+    std::cout << euclidean_distance(dls1, segment_data<int>(Point(2, 0), Point(3, 0))) << std::endl;
     assert_s(intersects(dls1, dls3), "intersects1");
-    assert_s(!intersects(dls1, directed_line_segment_data<int>(Point(2, 0), Point(3, 0))), "intersects2");
-    assert_s(boundaries_intersect(dls1, dls2), "bi");
+    assert_s(!intersects(dls1, segment_data<int>(Point(2, 0), Point(3, 0))), "intersects2");
     assert_s(abuts(dls1, dls2), "abuts");
     Point p;
     bool ir = intersection(p, dls1, dls2);
Added: trunk/libs/polygon/test/polygon_segment_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/polygon/test/polygon_segment_test.cpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,367 @@
+// Boost.Polygon library polygon_segment_test.cpp file
+
+//          Copyright Andrii Sydorchuk 2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#define BOOST_TEST_MODULE POLYGON_SEGMENT_TEST
+#include <boost/mpl/list.hpp>
+#include <boost/test/test_case_template.hpp>
+
+#include "boost/polygon/polygon.hpp"
+using namespace boost::polygon;
+
+typedef boost::mpl::list<int> test_types;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_data_test, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef segment_data<T> segment_type;
+  point_type point1(1, 2);
+  point_type point2(3, 4);
+  segment_type segment1(point1, point2);
+  segment_type segment2 = segment1;
+
+  BOOST_CHECK(segment1.low() == point1);
+  BOOST_CHECK(segment1.high() == point2);
+  BOOST_CHECK(segment1.get(LOW) == point1);
+  BOOST_CHECK(segment1.get(HIGH) == point2);
+  BOOST_CHECK(segment1 == segment2);
+  BOOST_CHECK(!(segment1 != segment2));
+  BOOST_CHECK(!(segment1 < segment2));
+  BOOST_CHECK(!(segment1 > segment1));
+  BOOST_CHECK(segment1 <= segment2);
+  BOOST_CHECK(segment1 >= segment2);
+  
+  segment1.low(point2);
+  segment1.high(point1);
+  BOOST_CHECK(segment1.low() == point2);
+  BOOST_CHECK(segment1.high() == point1);
+  BOOST_CHECK(!(segment1 == segment2));
+  BOOST_CHECK(segment1 != segment2);
+
+  segment2.set(LOW, point2);
+  segment2.set(HIGH, point1);
+  BOOST_CHECK(segment1 == segment2);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_traits_test, T, test_types) {
+  typedef point_data<T> point_type ;
+  typedef segment_data<T> segment_type;
+
+  point_type point1(1, 2);
+  point_type point2(3, 4);
+  segment_type segment = segment_mutable_traits<segment_type>::construct(point1, point2);
+
+  BOOST_CHECK(segment_traits<segment_type>::get(segment, LOW) == point1);
+  BOOST_CHECK(segment_traits<segment_type>::get(segment, HIGH) == point2);
+
+  segment_mutable_traits<segment_type>::set(segment, LOW, point2);
+  segment_mutable_traits<segment_type>::set(segment, HIGH, point1);
+
+  BOOST_CHECK(segment_traits<segment_type>::get(segment, LOW) == point2);
+  BOOST_CHECK(segment_traits<segment_type>::get(segment, HIGH) == point1);
+}
+
+template <typename T>
+struct Segment {
+  point_data<T> p0;
+  point_data<T> p1;
+};
+
+namespace boost {
+namespace polygon {
+  template <typename T>
+  struct geometry_concept< Segment<T> > { typedef segment_concept type; };
+
+  template <typename T>
+  struct segment_traits< Segment<T> > {
+    typedef T coordinate_type;
+    typedef point_data<T> point_type;
+    
+    static point_type get(const Segment<T>& segment, direction_1d dir) {
+      return dir.to_int() ? segment.p1 : segment.p0;
+    }
+  };
+
+  template <typename T>
+  struct segment_mutable_traits< Segment<T> > {
+    typedef point_data<T> point_type;
+
+    static inline void set(Segment<T>& segment, direction_1d dir, const point_type& point) {
+      if (dir.to_int()) {
+        segment.p1 = point;
+      } else {
+        segment.p0 = point;
+      }
+    }
+
+    static inline Segment<T> construct(const point_type& point1, const point_type& point2) {
+      Segment<T> segment;
+      segment.p0 = point1;
+      segment.p1 = point2;
+      return segment;
+    }
+  };
+}
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test1, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+
+  point_type point1(1, 2);
+  point_type point2(3, 4);
+  point_type point3(2, 3);
+  segment_type segment1 = construct<segment_type>(point1, point2);
+  BOOST_CHECK(segment1.p0 == point1);
+  BOOST_CHECK(segment1.p1 == point2);
+  BOOST_CHECK(get(segment1, LOW) == point1);
+  BOOST_CHECK(low(segment1) == point1);
+  BOOST_CHECK(get(segment1, HIGH) == point2);
+  BOOST_CHECK(high(segment1) == point2);
+  BOOST_CHECK(center(segment1) == point3);
+
+  set(segment1, LOW, point2);
+  set(segment1, HIGH, point1);
+  BOOST_CHECK(segment1.p0 == point2);
+  BOOST_CHECK(segment1.p1 == point1);
+  BOOST_CHECK(get(segment1, LOW) == point2);
+  BOOST_CHECK(get(segment1, HIGH) == point1);
+  low(segment1, point1);
+  high(segment1, point2);
+  BOOST_CHECK(segment1.p0 == point1);
+  BOOST_CHECK(segment1.p1 == point2);
+
+  segment_data<T> segment2 = copy_construct< segment_data<T> >(segment1);
+  BOOST_CHECK(segment1.p0 == segment2.low());
+  BOOST_CHECK(segment1.p1 == segment2.high());
+  BOOST_CHECK(equivalence(segment1, segment2));
+
+  segment_data<T> segment3 = construct< segment_data<T> >(point2, point1);
+  assign(segment1, segment3);
+  BOOST_CHECK(segment1.p0 == point2);
+  BOOST_CHECK(segment1.p1 == point1);
+  BOOST_CHECK(!equivalence(segment1, segment2));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test2, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+  
+  point_type point1(1, 2);
+  point_type point2(2, 4);
+  point_type point3(0, 0);
+  point_type point4(5, 10);
+  point_type point5(1, 3);
+  point_type point6(2, 3);
+  point_type point7(100, 201);
+  point_type point8(100, 200);
+  point_type point9(100, 199);
+  segment_type segment = construct<segment_type>(point1, point2);
+
+  BOOST_CHECK(on_above_or_below(segment, point1) == 0);
+  BOOST_CHECK(on_above_or_below(segment, point2) == 0);
+  BOOST_CHECK(on_above_or_below(segment, point3) == 0);
+  BOOST_CHECK(on_above_or_below(segment, point4) == 0);
+  BOOST_CHECK(on_above_or_below(segment, point5) == 1);
+  BOOST_CHECK(on_above_or_below(segment, point6) == -1);
+  BOOST_CHECK(on_above_or_below(segment, point7) == 1);
+  BOOST_CHECK(on_above_or_below(segment, point8) == 0);
+  BOOST_CHECK(on_above_or_below(segment, point9) == -1);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test3, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+
+  point_type point1(1, 2);
+  point_type point2(3, 6);
+  point_type point3(2, 4);
+  point_type point4(4, 8);
+  point_type point5(0, 0);
+  segment_type segment = construct<segment_type>(point1, point2);
+
+  BOOST_CHECK(contains(segment, point1, true));
+  BOOST_CHECK(contains(segment, point2, true));
+  BOOST_CHECK(!contains(segment, point1, false));
+  BOOST_CHECK(!contains(segment, point2, false));
+  BOOST_CHECK(contains(segment, point3, false));
+  BOOST_CHECK(!contains(segment, point4, true));
+  BOOST_CHECK(!contains(segment, point5, true));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test4, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+
+  point_type point1(0, 0);
+  point_type point2(10, 0);
+  point_type point3(5, 0);
+  point_type point4(-1, 0);
+  point_type point5(11, 0);
+  segment_type segment = construct<segment_type>(point1, point2);
+
+  BOOST_CHECK(contains(segment, point1, true));
+  BOOST_CHECK(contains(segment, point2, true));
+  BOOST_CHECK(!contains(segment, point1, false));
+  BOOST_CHECK(!contains(segment, point2, false));
+  BOOST_CHECK(contains(segment, point3, false));
+  BOOST_CHECK(!contains(segment, point4, true));
+  BOOST_CHECK(!contains(segment, point5, true));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test5, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+
+  point_type point1(0, 0);
+  point_type point2(1, 2);
+  point_type point3(2, 4);
+  point_type point4(3, 6);
+  point_type point5(4, 8);
+  point_type point6(5, 10);
+  segment_type segment1 = construct<segment_type>(point2, point5);
+  segment_type segment2 = construct<segment_type>(point3, point4);
+  segment_type segment3 = construct<segment_type>(point1, point3);
+  segment_type segment4 = construct<segment_type>(point4, point6);
+
+  BOOST_CHECK(contains(segment1, segment2, false));
+  BOOST_CHECK(!contains(segment2, segment1, true));
+  BOOST_CHECK(!contains(segment1, segment3, true));
+  BOOST_CHECK(!contains(segment1, segment4, true));
+  BOOST_CHECK(contains(segment1, segment1, true));
+  BOOST_CHECK(!contains(segment1, segment1, false));
+}
+
+template<typename T>
+struct Transformer {
+  void scale(T& x, T& y) const {
+    x *= 2;
+    y *= 2;
+  }
+
+  void transform(T& x, T& y) const {
+    T tmp = x;
+    x = y;
+    y = tmp;
+  }
+};
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test6, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+
+  point_type point1(1, 2);
+  point_type point2(4, 6);
+  segment_type segment1 = construct<segment_type>(point1, point2);
+
+  scale_up(segment1, 3);
+  BOOST_CHECK(low(segment1) == point_type(3, 6));
+  BOOST_CHECK(high(segment1) == point_type(12, 18));  
+
+  scale_down(segment1, 3);
+  BOOST_CHECK(low(segment1) == point1);
+  BOOST_CHECK(high(segment1) == point2);
+  BOOST_CHECK(length(segment1) == 5);
+
+  move(segment1, HORIZONTAL, 1);
+  move(segment1, VERTICAL, 2);
+  BOOST_CHECK(low(segment1) == point_type(2, 4));
+  BOOST_CHECK(high(segment1) == point_type(5, 8));
+  BOOST_CHECK(length(segment1) == 5);
+
+  convolve(segment1, point_type(1, 2));
+  BOOST_CHECK(low(segment1) == point_type(3, 6));
+  BOOST_CHECK(high(segment1) == point_type(6, 10));
+
+  deconvolve(segment1, point_type(2, 4));
+  BOOST_CHECK(low(segment1) == point1);
+  BOOST_CHECK(high(segment1) == point2);
+
+  scale(segment1, Transformer<T>());
+  BOOST_CHECK(low(segment1) == point_type(2, 4));
+  BOOST_CHECK(high(segment1) == point_type(8, 12));
+  transform(segment1, Transformer<T>());
+  BOOST_CHECK(low(segment1) == point_type(4, 2));
+  BOOST_CHECK(high(segment1) == point_type(12, 8));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test7, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+
+  segment_type segment1 = construct<segment_type>(point_type(0, 0), point_type(1, 2));
+  segment_type segment2 = construct<segment_type>(point_type(1, 2), point_type(2, 4));
+  segment_type segment3 = construct<segment_type>(point_type(2, 4), point_type(0, 4));
+  segment_type segment4 = construct<segment_type>(point_type(0, 4), point_type(0, 0));
+
+  BOOST_CHECK(abuts(segment1, segment2, HIGH));
+  BOOST_CHECK(abuts(segment2, segment3, HIGH));
+  BOOST_CHECK(abuts(segment3, segment4, HIGH));
+  BOOST_CHECK(abuts(segment4, segment1, HIGH));
+
+  BOOST_CHECK(!abuts(segment1, segment2, LOW));
+  BOOST_CHECK(!abuts(segment2, segment3, LOW));
+  BOOST_CHECK(!abuts(segment3, segment4, LOW));
+  BOOST_CHECK(!abuts(segment4, segment1, LOW));
+
+  BOOST_CHECK(abuts(segment2, segment1));
+  BOOST_CHECK(abuts(segment3, segment2));
+  BOOST_CHECK(abuts(segment4, segment3));
+  BOOST_CHECK(abuts(segment1, segment4));
+
+  BOOST_CHECK(!abuts(segment1, segment3));
+  BOOST_CHECK(!abuts(segment2, segment4));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test8, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+
+  point_type point;
+  segment_type segment1 = construct<segment_type>(point_type(0, 0), point_type(2, 2));
+  segment_type segment2 = construct<segment_type>(point_type(1, 1), point_type(3, 3));
+  
+  BOOST_CHECK(!intersection(point, segment1, segment2));
+  BOOST_CHECK(intersects(segment1, segment2));
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test9, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+
+  point_type point1(1, 2);
+  point_type point2(7, 10);
+  segment_type segment1 = construct<segment_type>(point1, point2);
+
+  BOOST_CHECK(euclidean_distance(segment1, point1) == 0.0);
+  BOOST_CHECK(euclidean_distance(segment1, point2) == 0.0);
+  BOOST_CHECK(euclidean_distance(segment1, point_type(10, 14)) == 5.0);
+  BOOST_CHECK(euclidean_distance(segment1, point_type(-3, -1)) == 5.0);
+  BOOST_CHECK(euclidean_distance(segment1, point_type(0, 9)) == 5.0);
+  BOOST_CHECK(euclidean_distance(segment1, point_type(8, 3)) == 5.0);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test10, T, test_types) {
+  typedef point_data<T> point_type;
+  typedef Segment<T> segment_type;
+
+  segment_type segment1 = construct<segment_type>(point_type(0, 0), point_type(3, 4));
+  segment_type segment2 = construct<segment_type>(point_type(2, 0), point_type(0, 2));
+  segment_type segment3 = construct<segment_type>(point_type(1, -7), point_type(10, 5));
+  segment_type segment4 = construct<segment_type>(point_type(7, 7), point_type(10, 11));
+  segment_type segment5 = construct<segment_type>(point_type(1, 1), point_type(-1, 3));
+  segment_type segment6 = construct<segment_type>(point_type(0, 0), point_type(1, 1));
+
+  BOOST_CHECK(intersects(segment1, segment2, false));
+  BOOST_CHECK(euclidean_distance(segment1, segment2) == 0.0);
+  BOOST_CHECK(!intersects(segment1, segment3, true));
+  BOOST_CHECK(euclidean_distance(segment1, segment3) == 5.0);
+  BOOST_CHECK(!intersects(segment1, segment4, true));
+  BOOST_CHECK(euclidean_distance(segment1, segment4) == 5.0);
+  BOOST_CHECK(intersects(segment2, segment5, false));
+  BOOST_CHECK(intersects(segment2, segment6, false));
+}
Added: trunk/libs/polygon/test/voronoi_builder_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/polygon/test/voronoi_builder_test.cpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,608 @@
+// Boost.Polygon library voronoi_builder_test.cpp file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <ctime>
+
+#define BOOST_TEST_MODULE voronoi_builder_test
+#include <boost/mpl/list.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/test/test_case_template.hpp>
+
+#include <boost/polygon/polygon.hpp>
+#include <boost/polygon/voronoi.hpp>
+using namespace boost::polygon;
+#include "voronoi_test_helper.hpp"
+
+typedef boost::mpl::list<int> test_types;
+typedef voronoi_diagram<double> vd_type;
+typedef vd_type::coordinate_type coordinate_type;
+typedef vd_type::edge_type voronoi_edge_type;
+typedef vd_type::const_cell_iterator const_cell_iterator;
+typedef vd_type::const_vertex_iterator const_vertex_iterator;
+
+#define CHECK_EQUAL_POINTS(p1, p2) \
+    BOOST_CHECK(p1.x() == static_cast<T>(p2.x())); \
+    BOOST_CHECK(p1.y() == static_cast<T>(p2.y()))
+
+#define CHECK_OUTPUT_SIZE(output, cells, vertices, edges) \
+    BOOST_CHECK(output.num_cells() == cells); \
+    BOOST_CHECK(output.num_vertices() == vertices); \
+    BOOST_CHECK(output.num_edges() == edges)
+
+#define VERIFY_OUTPUT(output) \
+    BOOST_CHECK(voronoi_test_helper::verify_output(output, \
+        voronoi_test_helper::HALF_EDGE_ORIENTATION)); \
+    BOOST_CHECK(voronoi_test_helper::verify_output(output, \
+        voronoi_test_helper::CELL_CONVEXITY)); \
+    BOOST_CHECK(voronoi_test_helper::verify_output(output, \
+        voronoi_test_helper::INCIDENT_EDGES_CCW_ORDER)); \
+    BOOST_CHECK(voronoi_test_helper::verify_output(output, \
+        voronoi_test_helper::NO_HALF_EDGE_INTERSECTIONS))
+
+#define VERIFY_NO_HALF_EDGE_INTERSECTIONS(output) \
+    BOOST_CHECK(voronoi_test_helper::verify_output(output, \
+        voronoi_test_helper::NO_HALF_EDGE_INTERSECTIONS))
+
+// Sites: (0, 0).
+BOOST_AUTO_TEST_CASE_TEMPLATE(single_site_test, T, test_types) {
+  std::vector< point_data<T> > points;
+  points.push_back(point_data<T>(0, 0));
+  vd_type test_output;
+  construct_voronoi(points.begin(), points.end(), &test_output);
+  VERIFY_OUTPUT(test_output);
+
+  BOOST_CHECK(test_output.cells().size() == 1);
+  CHECK_OUTPUT_SIZE(test_output, 1, 0, 0);
+
+  const_cell_iterator it = test_output.cells().begin();
+  BOOST_CHECK(it->incident_edge() == NULL);
+}
+
+// Sites: (0, 0), (0, 1).
+BOOST_AUTO_TEST_CASE_TEMPLATE(collinear_sites_test1, T, test_types) {
+  std::vector< point_data<T> > points;
+  points.push_back(point_data<T>(0, 0));
+  points.push_back(point_data<T>(0, 1));
+  vd_type test_output;
+  construct_voronoi(points.begin(), points.end(), &test_output);
+  VERIFY_OUTPUT(test_output);
+  CHECK_OUTPUT_SIZE(test_output, 2, 0, 1);
+
+  const_cell_iterator cell_it = test_output.cells().begin();
+  cell_it++;
+
+  const voronoi_edge_type *edge1_1 = cell_it->incident_edge();
+  const voronoi_edge_type *edge1_2 = edge1_1->twin();
+
+  BOOST_CHECK_EQUAL(edge1_1->twin() == edge1_2, true);
+  BOOST_CHECK_EQUAL(edge1_2->twin() == edge1_1, true);
+
+  BOOST_CHECK_EQUAL(edge1_1->next() == edge1_1, true);
+  BOOST_CHECK_EQUAL(edge1_1->prev() == edge1_1, true);
+  BOOST_CHECK_EQUAL(edge1_1->rot_next() == NULL, true);
+  BOOST_CHECK_EQUAL(edge1_1->rot_prev() == NULL, true);
+
+  BOOST_CHECK_EQUAL(edge1_2->next() == edge1_2, true);
+  BOOST_CHECK_EQUAL(edge1_2->prev() == edge1_2, true);
+  BOOST_CHECK_EQUAL(edge1_2->rot_next() == NULL, true);
+  BOOST_CHECK_EQUAL(edge1_2->rot_prev() == NULL, true);
+}
+
+// Sites: (0, 0), (1, 1), (2, 2).
+BOOST_AUTO_TEST_CASE_TEMPLATE(collinear_sites_test2, T, test_types) {
+  std::vector< point_data<T> > points;
+  points.push_back(point_data<T>(0, 0));
+  points.push_back(point_data<T>(1, 1));
+  points.push_back(point_data<T>(2, 2));
+  vd_type test_output;
+  construct_voronoi(points.begin(), points.end(), &test_output);
+  VERIFY_OUTPUT(test_output);
+  CHECK_OUTPUT_SIZE(test_output, 3, 0, 2);
+
+  const_cell_iterator cell_it = test_output.cells().begin();
+  const voronoi_edge_type *edge1_1 = cell_it->incident_edge();
+  const voronoi_edge_type *edge1_2 = edge1_1->twin();
+  cell_it++;
+  cell_it++;
+  const voronoi_edge_type *edge2_2 = cell_it->incident_edge();
+  const voronoi_edge_type *edge2_1 = edge2_2->twin();
+
+  BOOST_CHECK_EQUAL(edge1_1->twin() == edge1_2 && edge1_2->twin() == edge1_1, true);
+  BOOST_CHECK_EQUAL(edge2_1->twin() == edge2_2 && edge2_2->twin() == edge2_1, true);
+
+  BOOST_CHECK_EQUAL(edge1_1->next() == edge1_1 && edge1_1->prev() == edge1_1, true);
+  BOOST_CHECK_EQUAL(edge1_1->rot_next() == NULL && edge1_1->rot_prev() == NULL, true);
+  BOOST_CHECK_EQUAL(edge1_2->rot_next() == NULL && edge1_2->rot_prev() == NULL, true);
+  BOOST_CHECK_EQUAL(edge2_1->rot_next() == NULL && edge2_1->rot_prev() == NULL, true);
+  BOOST_CHECK_EQUAL(edge2_2->next() == edge2_2 && edge2_2->prev() == edge2_2, true);
+  BOOST_CHECK_EQUAL(edge2_2->rot_next() == NULL && edge2_2->rot_prev() == NULL, true);
+
+  BOOST_CHECK_EQUAL(edge1_2->next() == edge2_1 && edge1_2->prev() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge2_1->next() == edge1_2 && edge2_1->prev() == edge1_2, true);
+}
+
+// Sites: (0, 0), (0, 4), (2, 1).
+BOOST_AUTO_TEST_CASE_TEMPLATE(triangle_test1, T, test_types) {
+  point_data<T> point1(0, 0);
+  point_data<T> point2(0, 4);
+  point_data<T> point3(2, 1);
+  std::vector< point_data<T> > points;
+  points.push_back(point1);
+  points.push_back(point2);
+  points.push_back(point3);
+  vd_type test_output;
+  construct_voronoi(points.begin(), points.end(), &test_output);
+  VERIFY_OUTPUT(test_output);
+  CHECK_OUTPUT_SIZE(test_output, 3, 1, 3);
+
+  const_vertex_iterator it = test_output.vertices().begin();
+  BOOST_CHECK_EQUAL(it->vertex().x() == static_cast<coordinate_type>(0.25) &&
+                    it->vertex().y() == static_cast<coordinate_type>(2.0), true);
+
+  const voronoi_edge_type *edge1_1 = it->incident_edge();
+  const voronoi_edge_type *edge1_2 = edge1_1->twin();
+  CHECK_EQUAL_POINTS(edge1_1->cell()->point0(), point2);
+  CHECK_EQUAL_POINTS(edge1_2->cell()->point0(), point3);
+
+  const voronoi_edge_type *edge2_1 = edge1_1->rot_prev();
+  const voronoi_edge_type *edge2_2 = edge2_1->twin();
+  CHECK_EQUAL_POINTS(edge2_1->cell()->point0(), point3);
+  CHECK_EQUAL_POINTS(edge2_2->cell()->point0(), point1);
+
+  const voronoi_edge_type *edge3_1 = edge2_1->rot_prev();
+  const voronoi_edge_type *edge3_2 = edge3_1->twin();
+  CHECK_EQUAL_POINTS(edge3_1->cell()->point0(), point1);
+  CHECK_EQUAL_POINTS(edge3_2->cell()->point0(), point2);
+
+  BOOST_CHECK_EQUAL(edge1_2->twin() == edge1_1, true);
+  BOOST_CHECK_EQUAL(edge2_2->twin() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge3_2->twin() == edge3_1, true);
+
+  BOOST_CHECK_EQUAL(edge1_1->prev() == edge3_2 && edge1_1->next() == edge3_2, true);
+  BOOST_CHECK_EQUAL(edge2_1->prev() == edge1_2 && edge2_1->next() == edge1_2, true);
+  BOOST_CHECK_EQUAL(edge3_1->prev() == edge2_2 && edge3_1->next() == edge2_2, true);
+
+  BOOST_CHECK_EQUAL(edge1_2->next() == edge2_1 && edge1_2->prev() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge2_2->next() == edge3_1 && edge2_2->prev() == edge3_1, true);
+  BOOST_CHECK_EQUAL(edge3_2->next() == edge1_1 && edge3_2->prev() == edge1_1, true);
+
+  BOOST_CHECK_EQUAL(edge1_1->rot_next() == edge3_1, true);
+  BOOST_CHECK_EQUAL(edge3_1->rot_next() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge2_1->rot_next() == edge1_1, true);
+}
+
+// Sites: (0, 1), (2, 0), (2, 4).
+BOOST_AUTO_TEST_CASE_TEMPLATE(triangle_test2, T, test_types) {
+  point_data<T> point1(0, 1);
+  point_data<T> point2(2, 0);
+  point_data<T> point3(2, 4);
+  std::vector< point_data<T> > points;
+  points.push_back(point1);
+  points.push_back(point2);
+  points.push_back(point3);
+  vd_type test_output;
+  construct_voronoi(points.begin(), points.end(), &test_output);
+  VERIFY_OUTPUT(test_output);
+  CHECK_OUTPUT_SIZE(test_output, 3, 1, 3);
+
+  const_vertex_iterator it = test_output.vertices().begin();
+  BOOST_CHECK_EQUAL(it->vertex().x() == static_cast<coordinate_type>(1.75) &&
+                    it->vertex().y() == static_cast<coordinate_type>(2.0), true);
+
+  const voronoi_edge_type *edge1_1 = it->incident_edge();
+  const voronoi_edge_type *edge1_2 = edge1_1->twin();
+  CHECK_EQUAL_POINTS(edge1_1->cell()->point0(), point3);
+  CHECK_EQUAL_POINTS(edge1_2->cell()->point0(), point2);
+
+  const voronoi_edge_type *edge2_1 = edge1_1->rot_prev();
+  const voronoi_edge_type *edge2_2 = edge2_1->twin();
+  CHECK_EQUAL_POINTS(edge2_1->cell()->point0(), point2);
+  CHECK_EQUAL_POINTS(edge2_2->cell()->point0(), point1);
+
+  const voronoi_edge_type *edge3_1 = edge2_1->rot_prev();
+  const voronoi_edge_type *edge3_2 = edge3_1->twin();
+  CHECK_EQUAL_POINTS(edge3_1->cell()->point0(), point1);
+  CHECK_EQUAL_POINTS(edge3_2->cell()->point0(), point3);
+
+  BOOST_CHECK_EQUAL(edge1_2->twin() == edge1_1, true);
+  BOOST_CHECK_EQUAL(edge2_2->twin() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge3_2->twin() == edge3_1, true);
+
+  BOOST_CHECK_EQUAL(edge1_1->prev() == edge3_2 && edge1_1->next() == edge3_2, true);
+  BOOST_CHECK_EQUAL(edge2_1->prev() == edge1_2 && edge2_1->next() == edge1_2, true);
+  BOOST_CHECK_EQUAL(edge3_1->prev() == edge2_2 && edge3_1->next() == edge2_2, true);
+
+  BOOST_CHECK_EQUAL(edge1_2->next() == edge2_1 && edge1_2->prev() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge2_2->next() == edge3_1 && edge2_2->prev() == edge3_1, true);
+  BOOST_CHECK_EQUAL(edge3_2->next() == edge1_1 && edge3_2->prev() == edge1_1, true);
+
+  BOOST_CHECK_EQUAL(edge1_1->rot_next() == edge3_1, true);
+  BOOST_CHECK_EQUAL(edge3_1->rot_next() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge2_1->rot_next() == edge1_1, true);
+}
+
+// Sites: (0, 0), (0, 1), (1, 0), (1, 1).
+BOOST_AUTO_TEST_CASE_TEMPLATE(square_test1, T, test_types) {
+  point_data<T> point1(0, 0);
+  point_data<T> point2(0, 1);
+  point_data<T> point3(1, 0);
+  point_data<T> point4(1, 1);
+  std::vector< point_data<T> > points;
+  points.push_back(point1);
+  points.push_back(point2);
+  points.push_back(point3);
+  points.push_back(point4);
+  vd_type test_output;
+  construct_voronoi(points.begin(), points.end(), &test_output);
+  VERIFY_OUTPUT(test_output);
+  CHECK_OUTPUT_SIZE(test_output, 4, 1, 4);
+
+  // Check voronoi vertex.
+  const_vertex_iterator it = test_output.vertices().begin();
+  BOOST_CHECK_EQUAL(it->vertex().x() == static_cast<coordinate_type>(0.5) &&
+                    it->vertex().y() == static_cast<coordinate_type>(0.5), true);
+
+  // Check voronoi edges.
+  const voronoi_edge_type *edge1_1 = it->incident_edge();
+  const voronoi_edge_type *edge1_2 = edge1_1->twin();
+  CHECK_EQUAL_POINTS(edge1_1->cell()->point0(), points[3]);
+  CHECK_EQUAL_POINTS(edge1_2->cell()->point0(), points[2]);
+
+  const voronoi_edge_type *edge2_1 = edge1_1->rot_prev();
+  const voronoi_edge_type *edge2_2 = edge2_1->twin();
+  CHECK_EQUAL_POINTS(edge2_1->cell()->point0(), points[2]);
+  CHECK_EQUAL_POINTS(edge2_2->cell()->point0(), points[0]);
+
+  const voronoi_edge_type *edge3_1 = edge2_1->rot_prev();
+  const voronoi_edge_type *edge3_2 = edge3_1->twin();
+  CHECK_EQUAL_POINTS(edge3_1->cell()->point0(), points[0]);
+  CHECK_EQUAL_POINTS(edge3_2->cell()->point0(), points[1]);
+
+  const voronoi_edge_type *edge4_1 = edge3_1->rot_prev();
+  const voronoi_edge_type *edge4_2 = edge4_1->twin();
+  CHECK_EQUAL_POINTS(edge4_1->cell()->point0(), points[1]);
+  CHECK_EQUAL_POINTS(edge4_2->cell()->point0(), points[3]);
+
+  BOOST_CHECK_EQUAL(edge1_2->twin() == edge1_1, true);
+  BOOST_CHECK_EQUAL(edge2_2->twin() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge3_2->twin() == edge3_1, true);
+  BOOST_CHECK_EQUAL(edge4_2->twin() == edge4_1, true);
+
+  BOOST_CHECK_EQUAL(edge1_1->prev() == edge4_2 && edge1_1->next() == edge4_2, true);
+  BOOST_CHECK_EQUAL(edge2_1->prev() == edge1_2 && edge2_1->next() == edge1_2, true);
+  BOOST_CHECK_EQUAL(edge3_1->prev() == edge2_2 && edge3_1->next() == edge2_2, true);
+  BOOST_CHECK_EQUAL(edge4_1->prev() == edge3_2 && edge4_1->next() == edge3_2, true);
+
+  BOOST_CHECK_EQUAL(edge1_2->next() == edge2_1 && edge1_2->prev() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge2_2->next() == edge3_1 && edge2_2->prev() == edge3_1, true);
+  BOOST_CHECK_EQUAL(edge3_2->next() == edge4_1 && edge3_2->prev() == edge4_1, true);
+  BOOST_CHECK_EQUAL(edge4_2->next() == edge1_1 && edge4_2->prev() == edge1_1, true);
+
+  BOOST_CHECK_EQUAL(edge1_1->rot_next() == edge4_1, true);
+  BOOST_CHECK_EQUAL(edge4_1->rot_next() == edge3_1, true);
+  BOOST_CHECK_EQUAL(edge3_1->rot_next() == edge2_1, true);
+  BOOST_CHECK_EQUAL(edge2_1->rot_next() == edge1_1, true);
+}
+
+#ifdef NDEBUG
+BOOST_AUTO_TEST_CASE_TEMPLATE(grid_test, T, test_types) {
+  vd_type test_output_small, test_output_large;
+  std::vector< point_data<T> > point_vec_small, point_vec_large;
+  int grid_size[] = {10, 33, 101};
+  int max_value[] = {10, 33, 101};
+  int array_length = sizeof(grid_size) / sizeof(int);
+  for (int k = 0; k < array_length; k++) {
+    test_output_small.clear();
+    test_output_large.clear();
+    point_vec_small.clear();
+    point_vec_large.clear();
+    int koef = std::numeric_limits<int>::max() / max_value[k];
+    for (int i = 0; i < grid_size[k]; i++)
+      for (int j = 0; j < grid_size[k]; j++) {
+        point_vec_small.push_back(point_data<T>(i, j));
+        point_vec_large.push_back(point_data<T>(koef * i, koef * j));
+      }
+    construct_voronoi(point_vec_small.begin(), point_vec_small.end(), &test_output_small);
+    construct_voronoi(point_vec_large.begin(), point_vec_large.end(), &test_output_large);
+    VERIFY_OUTPUT(test_output_small);
+    VERIFY_OUTPUT(test_output_large);
+    unsigned int num_cells = grid_size[k] * grid_size[k];
+    unsigned int num_vertices = num_cells - 2 * grid_size[k] + 1;
+    unsigned int num_edges = 2 * num_cells - 2 * grid_size[k];
+    CHECK_OUTPUT_SIZE(test_output_small, num_cells, num_vertices, num_edges);
+    CHECK_OUTPUT_SIZE(test_output_large, num_cells, num_vertices, num_edges);
+  }
+}
+#endif
+
+#ifdef NDEBUG
+BOOST_AUTO_TEST_CASE_TEMPLATE(random_test, T, test_types) {
+  boost::mt19937 gen(static_cast<unsigned int>(time(NULL)));
+  vd_type test_output_small, test_output_large;
+  std::vector< point_data<T> > point_vec_small, point_vec_large;
+  int num_points[] = {10, 100, 1000, 10000};
+  int num_runs[] = {1000, 100, 10, 1};
+  int mod_koef[] = {10, 100, 100, 1000};
+  int max_value[] = {5, 50, 50, 5000};
+  int array_length = sizeof(num_points) / sizeof(int);
+  for (int k = 0; k < array_length; k++) {
+    int koef = std::numeric_limits<int>::max() / max_value[k];
+    for (int i = 0; i < num_runs[k]; i++) {
+      test_output_small.clear();
+      test_output_large.clear();
+      point_vec_small.clear();
+      point_vec_large.clear();
+      for (int j = 0; j < num_points[k]; j++) {
+        T x = gen() % mod_koef[k] - mod_koef[k] / 2;
+        T y = gen() % mod_koef[k] - mod_koef[k] / 2;
+        point_vec_small.push_back(point_data<T>(x, y));
+        point_vec_large.push_back(point_data<T>(koef * x, koef * y));
+      }
+      construct_voronoi(point_vec_small.begin(), point_vec_small.end(), &test_output_small);
+      construct_voronoi(point_vec_large.begin(), point_vec_large.end(), &test_output_large);
+      VERIFY_OUTPUT(test_output_small);
+      VERIFY_OUTPUT(test_output_large);
+      BOOST_CHECK_EQUAL(test_output_small.num_cells(), test_output_large.num_cells());
+      BOOST_CHECK_EQUAL(test_output_small.num_vertices(), test_output_large.num_vertices());
+      BOOST_CHECK_EQUAL(test_output_small.num_edges(), test_output_large.num_edges());
+    }
+  }
+}
+#endif
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_sites_test1, T, test_types) {
+  vd_type test_output;
+  std::vector< segment_data<T> > segments;
+  point_data<T> point1(0, 0);
+  point_data<T> point2(1, 1);
+  segments.push_back(segment_data<T>(point1, point2));
+  construct_voronoi(segments.begin(), segments.end(), &test_output);
+  CHECK_OUTPUT_SIZE(test_output, 3, 0, 2);
+  VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_sites_test2, T, test_types) {
+  vd_type test_output;
+  std::vector< point_data<T> > points;
+  std::vector< segment_data<T> > segments;
+  point_data<T> point1(0, 0);
+  point_data<T> point2(4, 4);
+  point_data<T> point3(3, 1);
+  point_data<T> point4(1, 3);
+  segments.push_back(segment_data<T>(point1, point2));
+  points.push_back(point3);
+  points.push_back(point4);
+  construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+  CHECK_OUTPUT_SIZE(test_output, 5, 4, 8);
+  VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_sites_test3, T, test_types) {
+  vd_type test_output;
+  std::vector< point_data<T> > points;
+  std::vector< segment_data<T> > segments;
+  point_data<T> point1(4, 0);
+  point_data<T> point2(0, 4);
+  point_data<T> point3(3, 3);
+  point_data<T> point4(1, 1);
+  segments.push_back(segment_data<T>(point1, point2));
+  points.push_back(point3);
+  points.push_back(point4);
+  construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+  CHECK_OUTPUT_SIZE(test_output, 5, 4, 8);
+  VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_sites_test4, T, test_types) {
+  vd_type test_output;
+  std::vector< point_data<T> > points;
+  std::vector< segment_data<T> > segments;
+  point_data<T> point1(4, 0);
+  point_data<T> point2(0, 4);
+  point_data<T> point3(3, 2);
+  point_data<T> point4(2, 3);
+  segments.push_back(segment_data<T>(point1, point2));
+  points.push_back(point3);
+  points.push_back(point4);
+  construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+  CHECK_OUTPUT_SIZE(test_output, 5, 3, 7);
+  VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_site_test5, T, test_types) {
+  vd_type test_output;
+  std::vector< point_data<T> > points;
+  std::vector< segment_data<T> > segments;
+  point_data<T> point1(0, 0);
+  point_data<T> point2(0, 8);
+  point_data<T> point3(-2, -2);
+  point_data<T> point4(-2, 4);
+  point_data<T> point5(-2, 10);
+  segments.push_back(segment_data<T>(point1, point2));
+  points.push_back(point3);
+  points.push_back(point4);
+  points.push_back(point5);
+  construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+  CHECK_OUTPUT_SIZE(test_output, 6, 4, 9);
+  VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_site_test6, T, test_types) {
+  vd_type test_output;
+  std::vector< point_data<T> > points;
+  std::vector< segment_data<T> > segments;
+  point_data<T> point1(-1, 1);
+  point_data<T> point2(1, 0);
+  point_data<T> point3(1, 2);
+  segments.push_back(segment_data<T>(point2, point3));
+  points.push_back(point1);
+  construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+  CHECK_OUTPUT_SIZE(test_output, 4, 2, 5);
+  VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_site_test7, T, test_types) {
+  vd_type test_output;
+  std::vector< segment_data<T> > segments;
+  point_data<T> point1(0, 0);
+  point_data<T> point2(4, 0);
+  point_data<T> point3(0, 4);
+  point_data<T> point4(4, 4);
+  segments.push_back(segment_data<T>(point1, point2));
+  segments.push_back(segment_data<T>(point2, point3));
+  segments.push_back(segment_data<T>(point3, point4));
+  construct_voronoi(segments.begin(), segments.end(), &test_output);
+  CHECK_OUTPUT_SIZE(test_output, 7, 6, 12);
+  VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_site_test8, T, test_types) {
+  vd_type test_output;
+  std::vector< segment_data<T> > segments;
+  point_data<T> point1(0, 0);
+  point_data<T> point2(4, 0);
+  point_data<T> point3(4, 4);
+  point_data<T> point4(0, 4);
+  segments.push_back(segment_data<T>(point1, point2));
+  segments.push_back(segment_data<T>(point2, point3));
+  segments.push_back(segment_data<T>(point3, point4));
+  segments.push_back(segment_data<T>(point4, point1));
+  construct_voronoi(segments.begin(), segments.end(), &test_output);
+  CHECK_OUTPUT_SIZE(test_output, 8, 5, 12);
+  VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+}
+
+#ifdef NDEBUG
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_grid_test, T, test_types) {
+  vd_type test_output_small, test_output_large;
+  std::vector< segment_data<T> > segments_small, segments_large;
+  int grid_size[] = {10, 27, 53};
+  int max_value[] = {100, 330, 1000};
+  int array_length = sizeof(grid_size) / sizeof(int);
+  for (int k = 0; k < array_length; k++) {
+    test_output_small.clear();
+    test_output_large.clear();
+    segments_small.clear();
+    segments_large.clear();
+    int cur_sz = grid_size[k];
+    int koef = std::numeric_limits<int>::max() / max_value[k];
+    for (int i = 0; i < cur_sz + 1; i++)
+      for (int j = 0; j < cur_sz; j++) {
+        point_data<T> point1_1(10 * i, 10 * j);
+        point_data<T> point1_2(koef * 10 * i, koef * 10 * j);
+        point_data<T> point2_1(10 * i, 10 * j + 10);
+        point_data<T> point2_2(koef * 10 * i, koef * (10 * j + 10));
+        segments_small.push_back(segment_data<T>(point1_1, point2_1));
+        segments_large.push_back(segment_data<T>(point1_2, point2_2));
+        point_data<T> point3_1(10 * j, 10 * i);
+        point_data<T> point3_2(koef * 10 * j, koef * 10 * i);
+        point_data<T> point4_1(10 * j + 10, 10 * i);
+        point_data<T> point4_2(koef * (10 * j + 10), koef * 10 * i);
+        segments_small.push_back(segment_data<T>(point3_1, point4_1));
+        segments_large.push_back(segment_data<T>(point3_2, point4_2));
+      }
+    construct_voronoi(segments_small.begin(), segments_small.end(), &test_output_small);
+    construct_voronoi(segments_large.begin(), segments_large.end(), &test_output_large);
+    VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output_small);
+    VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output_large);
+    BOOST_CHECK_EQUAL(test_output_small.num_cells(), test_output_large.num_cells());
+    BOOST_CHECK_EQUAL(test_output_small.num_vertices(), test_output_large.num_vertices());
+    BOOST_CHECK_EQUAL(test_output_small.num_edges(), test_output_large.num_edges());
+  }
+}
+#endif
+
+#ifdef NDEBUG
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_random_test1, T, test_types) {
+  boost::mt19937 gen(static_cast<unsigned int>(time(NULL)));
+  vd_type test_output;
+  std::vector< point_data<T> > points;
+  std::vector< segment_data<T> > segments;
+  int num_runs = 1000;
+  int num_segments = 10;
+  points.push_back(point_data<T>(-100, -100));
+  points.push_back(point_data<T>(-100, 100));
+  points.push_back(point_data<T>(100, -100));
+  points.push_back(point_data<T>(100, 100));
+  for (int i = 0; i < num_runs; i++) {
+    test_output.clear();
+    segments.clear();
+    for (int j = 0; j < num_segments; j++) {
+      T x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+      while (x1 == x2 && y1 == y2) {
+        x1 = (gen() % 100) - 50;
+        y1 = (gen() % 100) - 50;
+        x2 = (gen() % 100) - 50;
+        y2 = (gen() % 100) - 50;
+      }
+      point_data<T> point1(x1, y1);
+      point_data<T> point2(x2, y2);
+      segments.push_back(segment_data<T>(point1, point2));
+    }
+    voronoi_test_helper::clean_segment_set(segments);
+    construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), &test_output);
+    VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output);
+  }
+}
+#endif
+
+#ifdef NDEBUG
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_random_test2, T, test_types) {
+  boost::mt19937 gen(static_cast<unsigned int>(time(NULL)));
+  vd_type test_output_small, test_output_large;
+  std::vector< segment_data<T> > segments_small, segments_large;
+  int num_segments[] = {5, 25, 125, 625};
+  int num_runs[] = {1000, 100, 10, 1};
+  int mod_koef1[] = {10, 100, 200, 300};
+  int mod_koef2[] = {10, 20, 50, 100};
+  int max_value[] = {10, 60, 125, 200};
+  int array_length = sizeof(num_segments) / sizeof(int);
+  for (int k = 0; k < array_length; k++) {
+    int koef = std::numeric_limits<int>::max() / max_value[k];
+    for (int i = 0; i < num_runs[k]; i++) {
+      test_output_small.clear();
+      test_output_large.clear();
+      segments_small.clear();
+      segments_large.clear();
+      for (int j = 0; j < num_segments[k]; j++) {
+        T x1 = (gen() % mod_koef1[k]) - mod_koef1[k] / 2;
+        T y1 = (gen() % mod_koef1[k]) - mod_koef1[k] / 2;
+        T dx = 0, dy = 0;
+        while (dx == 0 && dy == 0) {
+          dx = (gen() % mod_koef2[k]) - mod_koef2[k] / 2;
+          dy = (gen() % mod_koef2[k]) - mod_koef2[k] / 2;
+        }
+        T x2 = x1 + dx;
+        T y2 = y1 + dy;
+        point_data<T> point1_small(x1, y1);
+        point_data<T> point2_small(x2, y2);
+        segments_small.push_back(segment_data<T>(point1_small, point2_small));
+      }
+      voronoi_test_helper::clean_segment_set(segments_small);
+      for (typename std::vector< segment_data<T> >::iterator it = segments_small.begin();
+           it != segments_small.end(); ++it) {
+        T x1 = it->low().x() * koef;
+        T y1 = it->low().y() * koef;
+        T x2 = it->high().x() * koef;
+        T y2 = it->high().y() * koef;
+        point_data<T> point1_large(x1, y1);
+        point_data<T> point2_large(x2, y2);
+        segments_large.push_back(segment_data<T>(point1_large, point2_large));
+      }
+      construct_voronoi(segments_small.begin(), segments_small.end(), &test_output_small);
+      construct_voronoi(segments_large.begin(), segments_large.end(), &test_output_large);
+      VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output_small);
+      VERIFY_NO_HALF_EDGE_INTERSECTIONS(test_output_large);
+      BOOST_CHECK_EQUAL(test_output_small.num_cells(), test_output_large.num_cells());
+      BOOST_CHECK_EQUAL(test_output_small.num_vertices(), test_output_large.num_vertices());
+      BOOST_CHECK_EQUAL(test_output_small.num_edges(), test_output_large.num_edges());
+    }
+  }
+}
+#endif
Added: trunk/libs/polygon/test/voronoi_ctypes_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/polygon/test/voronoi_ctypes_test.cpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,314 @@
+// Boost.Polygon library voronoi_ctypes_test.cpp file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <ctime>
+
+#define BOOST_TEST_MODULE voronoi_ctypes_test
+#include <boost/mpl/list.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/test/test_case_template.hpp>
+
+#include <boost/polygon/detail/voronoi_ctypes.hpp>
+using namespace boost::polygon::detail;
+
+type_converter_fpt to_fpt;
+
+BOOST_AUTO_TEST_CASE(ulp_comparison_test1) {
+  ulp_comparison<double> ulp_cmp;
+  uint64 a = 22;
+  uint64 b = 27;
+  fpt64 da, db;
+  memcpy(&da, &a, sizeof(uint64));
+  memcpy(&db, &b, sizeof(uint64));
+  BOOST_CHECK_EQUAL(ulp_cmp(da, db, 1), ulp_cmp.LESS);
+  BOOST_CHECK_EQUAL(ulp_cmp(db, da, 1), ulp_cmp.MORE);
+  BOOST_CHECK_EQUAL(ulp_cmp(da, db, 4), ulp_cmp.LESS);
+  BOOST_CHECK_EQUAL(ulp_cmp(da, db, 5), ulp_cmp.EQUAL);
+  BOOST_CHECK_EQUAL(ulp_cmp(da, db, 6), ulp_cmp.EQUAL);
+}
+
+BOOST_AUTO_TEST_CASE(ulp_comparison_test2) {
+  ulp_comparison<fpt64> ulp_cmp;
+  uint64 a = 0ULL;
+  uint64 b = 0x8000000000000002ULL;
+  fpt64 da, db;
+  memcpy(&da, &a, sizeof(uint64));
+  memcpy(&db, &b, sizeof(uint64));
+  BOOST_CHECK_EQUAL(ulp_cmp(da, db, 1), ulp_cmp.MORE);
+  BOOST_CHECK_EQUAL(ulp_cmp(db, da, 1), ulp_cmp.LESS);
+  BOOST_CHECK_EQUAL(ulp_cmp(da, db, 2), ulp_cmp.EQUAL);
+  BOOST_CHECK_EQUAL(ulp_cmp(da, db, 3), ulp_cmp.EQUAL);
+}
+
+BOOST_AUTO_TEST_CASE(fpt_exponent_accessor_test) {
+  typedef fpt_exponent_accessor<fpt64> fpt_ea;
+  fpt64 value = 15;
+  BOOST_CHECK_EQUAL(fpt_ea::set_exponent(value, 0), 3);
+  BOOST_CHECK_EQUAL(value, 1.875);
+  value = 0.0625;
+  BOOST_CHECK_EQUAL(fpt_ea::set_exponent(value, 0), -4);
+  BOOST_CHECK_EQUAL(value, 1.0);
+  value = -1.5;
+  BOOST_CHECK_EQUAL(fpt_ea::set_exponent(value, 4), 0);
+  BOOST_CHECK_EQUAL(value, -24.0);
+  value = 0.0;
+  BOOST_CHECK_EQUAL(fpt_ea::set_exponent(value, 4), fpt_ea::kMinExponent);
+  BOOST_CHECK_EQUAL(value, 16.0);
+  value = std::pow(2.0, 2000);
+  BOOST_CHECK_EQUAL(fpt_ea::set_exponent(value, 4), fpt_ea::kMaxExponent);
+  BOOST_CHECK_EQUAL(value, 16.0);
+}
+
+BOOST_AUTO_TEST_CASE(extended_exponent_fpt_test1) {
+  boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+  fpt64 b = 0.0;
+  efpt64 eeb(b);
+  for (int i = 0; i < 1000; ++i) {
+    fpt64 a = to_fpt(static_cast<int64>(gen()));
+    efpt64 eea(a);
+    efpt64 neg = -eea;
+    efpt64 sum = eea + eeb;
+    efpt64 dif = eea - eeb;
+    efpt64 mul = eea * eeb;
+    BOOST_CHECK_EQUAL(to_fpt(neg), -a);
+    BOOST_CHECK_EQUAL(to_fpt(sum), a + b);
+    BOOST_CHECK_EQUAL(to_fpt(dif), a - b);
+    BOOST_CHECK_EQUAL(to_fpt(mul), a * b);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extended_exponent_fpt_test2) {
+  boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+  fpt64 a = 0.0;
+  efpt64 eea(a);  
+  for (int i = 0; i < 1000; ++i) {
+    fpt64 b = to_fpt(static_cast<int64>(gen()));
+    if (b == 0.0)
+      continue;
+    efpt64 eeb(b);
+    efpt64 neg = -eea;
+    efpt64 sum = eea + eeb;
+    efpt64 dif = eea - eeb;
+    efpt64 mul = eea * eeb;
+    efpt64 div = eea / eeb;
+    BOOST_CHECK_EQUAL(to_fpt(neg), -a);
+    BOOST_CHECK_EQUAL(to_fpt(sum), a + b);
+    BOOST_CHECK_EQUAL(to_fpt(dif), a - b);
+    BOOST_CHECK_EQUAL(to_fpt(mul), a * b);
+    BOOST_CHECK_EQUAL(to_fpt(div), a / b);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extended_exponent_fpt_test3) {
+  boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+  for (int i = 0; i < 1000; ++i) {
+    fpt64 a = to_fpt(static_cast<int64>(gen()));
+    fpt64 b = to_fpt(static_cast<int64>(gen()));
+    if (b == 0.0)
+      continue;
+    efpt64 eea(a);
+    efpt64 eeb(b);
+    efpt64 neg = -eea;
+    efpt64 sum = eea + eeb;
+    efpt64 dif = eea - eeb;
+    efpt64 mul = eea * eeb;
+    efpt64 div = eea / eeb;
+    BOOST_CHECK_EQUAL(to_fpt(neg), -a);
+    BOOST_CHECK_EQUAL(to_fpt(sum), a + b);
+    BOOST_CHECK_EQUAL(to_fpt(dif), a - b);
+    BOOST_CHECK_EQUAL(to_fpt(mul), a * b);
+    BOOST_CHECK_EQUAL(to_fpt(div), a / b);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extended_exponent_fpt_test4) {
+  for (int exp = 0; exp < 64; ++exp)
+  for (int i = 1; i < 100; ++i) {
+    fpt64 a = i;
+    fpt64 b = to_fpt(1LL << exp);
+    efpt64 eea(a);
+    efpt64 eeb(b);
+    efpt64 neg = -eea;
+    efpt64 sum = eea + eeb;
+    efpt64 dif = eea - eeb;
+    efpt64 mul = eea * eeb;
+    efpt64 div = eea / eeb;
+    BOOST_CHECK_EQUAL(to_fpt(neg), -a);
+    BOOST_CHECK_EQUAL(to_fpt(sum), a + b);
+    BOOST_CHECK_EQUAL(to_fpt(dif), a - b);
+    BOOST_CHECK_EQUAL(to_fpt(mul), a * b);
+    BOOST_CHECK_EQUAL(to_fpt(div), a / b);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extended_exponent_fpt_test5) {
+  for (int i = 0; i < 100; ++i) {
+    efpt64 a(to_fpt(i * i));
+    efpt64 b = a.sqrt();
+    BOOST_CHECK_EQUAL(to_fpt(b), to_fpt(i));
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extended_exponent_fpt_test6) {
+  for (int i = -10; i <= 10; ++i) {
+    efpt64 a(to_fpt(i));
+    BOOST_CHECK_EQUAL(is_pos(a), i > 0);
+    BOOST_CHECK_EQUAL(is_neg(a), i < 0);
+    BOOST_CHECK_EQUAL(is_zero(a), !i);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extended_int_test1) {
+  typedef extended_int<1> eint32;
+  eint32 e1(0), e2(32), e3(-32);
+  BOOST_CHECK_EQUAL(e1.count(), 0);
+  BOOST_CHECK_EQUAL(e1.size(), 0U);
+  BOOST_CHECK_EQUAL(e2.count(), 1);
+  BOOST_CHECK_EQUAL(e2.chunks()[0], 32U);
+  BOOST_CHECK_EQUAL(e2.size(), 1U);
+  BOOST_CHECK_EQUAL(e3.count(), -1);
+  BOOST_CHECK_EQUAL(e3.chunks()[0], 32U);
+  BOOST_CHECK_EQUAL(e3.size(), 1U);
+}
+
+BOOST_AUTO_TEST_CASE(extended_int_test2) {
+  typedef extended_int<2> eint64;
+  int64 val64 = 0x7fffffffffffffffLL;
+  eint64 e1(0), e2(32), e3(-32), e4(val64), e5(-val64);
+  BOOST_CHECK_EQUAL(e1.count(), 0);
+  BOOST_CHECK_EQUAL(e2.count(), 1);
+  BOOST_CHECK_EQUAL(e2.chunks()[0], 32U);
+  BOOST_CHECK_EQUAL(e3.count(), -1);
+  BOOST_CHECK_EQUAL(e3.chunks()[0], 32U);
+  BOOST_CHECK_EQUAL(e4.count(), 2);
+  BOOST_CHECK_EQUAL(e4.chunks()[0], 0xffffffff);
+  BOOST_CHECK_EQUAL(e4.chunks()[1], val64 >> 32);
+  BOOST_CHECK_EQUAL(e5.count(), -2);
+  BOOST_CHECK_EQUAL(e5.chunks()[0], 0xffffffff);
+  BOOST_CHECK_EQUAL(e5.chunks()[1], val64 >> 32);
+}
+
+BOOST_AUTO_TEST_CASE(extended_int_test3) {
+  typedef extended_int<2> eint64;
+  std::vector<uint32> chunks;
+  chunks.push_back(1);
+  chunks.push_back(2);
+  eint64 e1(chunks, true), e2(chunks, false);
+  BOOST_CHECK_EQUAL(e1.count(), 2);
+  BOOST_CHECK_EQUAL(e1.chunks()[0], 2U);
+  BOOST_CHECK_EQUAL(e1.chunks()[1], 1U);
+  BOOST_CHECK_EQUAL(e2.count(), -2);
+  BOOST_CHECK_EQUAL(e2.chunks()[0], 2U);
+  BOOST_CHECK_EQUAL(e2.chunks()[1], 1U);
+}
+
+BOOST_AUTO_TEST_CASE(extended_int_test4) {
+  typedef extended_int<2> eint64;
+  std::vector<uint32> chunks;
+  chunks.push_back(1);
+  chunks.push_back(2);
+  eint64 e1(chunks, true), e2(chunks, false);
+  BOOST_CHECK_EQUAL(e1 == e2, false);
+  BOOST_CHECK_EQUAL(e1 == -e2, true);
+  BOOST_CHECK_EQUAL(e1 != e2, true);
+  BOOST_CHECK_EQUAL(e1 != -e2, false);
+  BOOST_CHECK_EQUAL(e1 < e2, false);
+  BOOST_CHECK_EQUAL(e1 < -e2, false);
+  BOOST_CHECK_EQUAL(e1 <= e2, false);
+  BOOST_CHECK_EQUAL(e1 <= -e2, true);
+  BOOST_CHECK_EQUAL(e1 > e2, true);
+  BOOST_CHECK_EQUAL(e1 > -e2, false);
+  BOOST_CHECK_EQUAL(e1 >= e2, true);
+  BOOST_CHECK_EQUAL(e1 >= -e2, true);
+}
+
+BOOST_AUTO_TEST_CASE(extended_int_test5) {
+  typedef extended_int<2> eint64;
+  boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+  for (int i = 0; i < 1000; ++i) {
+    int64 i1 = static_cast<int64>(gen());
+    int64 i2 = static_cast<int64>(gen());
+    eint64 e1(i1), e2(i2);
+    BOOST_CHECK_EQUAL(e1 == e2, i1 == i2);
+    BOOST_CHECK_EQUAL(e1 != e2, i1 != i2);
+    BOOST_CHECK_EQUAL(e1 > e2, i1 > i2);
+    BOOST_CHECK_EQUAL(e1 >= e2, i1 >= i2);
+    BOOST_CHECK_EQUAL(e1 < e2, i1 < i2);
+    BOOST_CHECK_EQUAL(e1 <= e2, i1 <= i2);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extended_int_test6) {
+  typedef extended_int<1> eint32;
+  eint32 e1(32);
+  eint32 e2 = -e1;
+  BOOST_CHECK_EQUAL(e2.count(), -1);
+  BOOST_CHECK_EQUAL(e2.size(), 1U);
+  BOOST_CHECK_EQUAL(e2.chunks()[0], 32U);
+}
+
+BOOST_AUTO_TEST_CASE(extended_int_test7) {
+  typedef extended_int<2> eint64;
+  boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+  for (int i = 0; i < 1000; ++i) {
+    int64 i1 = static_cast<int64>(gen()) >> 2;
+    int64 i2 = static_cast<int64>(gen()) >> 2;
+    eint64 e1(i1), e2(i2), e3(i1 + i2), e4(i1 - i2);
+    BOOST_CHECK(e1 + e2 == e3);
+    BOOST_CHECK(e1 - e2 == e4);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extended_int_test8) {
+  typedef extended_int<2> eint64;
+  boost::mt19937 gen(static_cast<uint32>(time(NULL)));
+  for (int i = 0; i < 1000; ++i) {
+    int64 i1 = static_cast<int32>(gen());
+    int64 i2 = static_cast<int32>(gen());
+    eint64 e1(i1), e2(i2), e3(i1 * i2);
+    BOOST_CHECK(e1 * e2 == e3);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(exnteded_int_test9) {
+  typedef extended_int<1> eint32;
+  for (int i = -10; i <= 10; ++i) {
+    for (int j = -10; j <= 10; ++j) {
+      eint32 e1(i), e2(j), e3(i+j), e4(i-j), e5(i*j);
+      BOOST_CHECK(e1 + e2 == e3);
+      BOOST_CHECK(e1 - e2 == e4);
+      BOOST_CHECK(e1 * e2 == e5);
+    }
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extended_int_test10) {
+  typedef extended_int<2> eint64;
+  boost::mt19937_64 gen(static_cast<uint32>(time(NULL)));
+  for (int i = 0; i < 100; ++i) {
+    int64 i1 = static_cast<int64>(gen()) >> 20;
+    int64 i2 = i1 >> 32;
+    eint64 e1(i1), e2(i2);
+    BOOST_CHECK(to_fpt(e1) == static_cast<fpt64>(i1));
+    BOOST_CHECK(to_fpt(e2) == static_cast<fpt64>(i2));
+  }
+}
+
+BOOST_AUTO_TEST_CASE(extened_int_test11) {
+  typedef extended_int<1> eint32;
+  typedef extended_int<64> eint2048;
+  eint32 two(2), one(1);
+  eint2048 value(1);
+  for (int i = 0; i < 1024; ++i)
+    value = value * two;
+  BOOST_CHECK_EQUAL(value.count(), 33);
+  for (size_t i = 1; i < value.size(); ++i)
+    BOOST_CHECK_EQUAL(value.chunks()[i-1], 0U);
+  BOOST_CHECK_EQUAL(value.chunks()[32], 1U);
+}
Added: trunk/libs/polygon/test/voronoi_predicates_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/polygon/test/voronoi_predicates_test.cpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,459 @@
+// Boost.Polygon library voronoi_predicates_test.cpp file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <map>
+
+#define BOOST_TEST_MODULE voronoi_predicates_test
+#include <boost/test/test_case_template.hpp>
+
+#include <boost/polygon/detail/voronoi_ctypes.hpp>
+#include <boost/polygon/detail/voronoi_predicates.hpp>
+#include <boost/polygon/detail/voronoi_structures.hpp>
+using namespace boost::polygon::detail;
+
+ulp_comparison<double> ulp_cmp;
+
+typedef voronoi_predicates< voronoi_ctype_traits<int> > VP;
+typedef point_2d<int> point_type;
+typedef site_event<int> site_type;
+typedef circle_event<double> circle_type;
+VP::event_comparison_predicate<site_type, circle_type> event_comparison;
+
+typedef beach_line_node_key<site_type> key_type;
+typedef VP::distance_predicate<site_type> distance_predicate_type;
+typedef VP::node_comparison_predicate<key_type> node_comparison_type;
+typedef std::map<key_type, int, node_comparison_type> beach_line_type;
+typedef beach_line_type::iterator bieach_line_iterator;
+distance_predicate_type distance_predicate;
+node_comparison_type node_comparison;
+
+typedef VP::circle_existence_predicate<site_type> CEP_type;
+typedef VP::mp_circle_formation_functor<site_type, circle_type> MP_CFF_type;
+typedef VP::lazy_circle_formation_functor<site_type, circle_type> lazy_CFF_type;
+VP::circle_formation_predicate<site_type, circle_type, CEP_type, MP_CFF_type> mp_predicate;
+VP::circle_formation_predicate<site_type, circle_type, CEP_type, lazy_CFF_type> lazy_predicate;
+
+#define CHECK_ORIENTATION(P1, P2, P3, R1, R2) \
+    BOOST_CHECK_EQUAL(VP::ot::eval(P1, P2, P3) == R1, true); \
+    BOOST_CHECK_EQUAL(VP::ot::eval(P1, P3, P2) == R2, true); \
+    BOOST_CHECK_EQUAL(VP::ot::eval(P2, P1, P3) == R2, true); \
+    BOOST_CHECK_EQUAL(VP::ot::eval(P2, P3, P1) == R1, true); \
+    BOOST_CHECK_EQUAL(VP::ot::eval(P3, P1, P2) == R1, true); \
+    BOOST_CHECK_EQUAL(VP::ot::eval(P3, P2, P1) == R2, true)
+
+#define CHECK_EVENT_COMPARISON(A, B, R1, R2) \
+    BOOST_CHECK_EQUAL(event_comparison(A, B), R1); \
+    BOOST_CHECK_EQUAL(event_comparison(B, A), R2)
+
+#define CHECK_DISTANCE_PREDICATE(S1, S2, S3, RES) \
+    BOOST_CHECK_EQUAL(distance_predicate(S1, S2, S3), RES)
+
+#define CHECK_NODE_COMPARISON(node, nodes, res, sz) \
+    for (int i = 0; i < sz; ++i) { \
+      BOOST_CHECK_EQUAL(node_comparison(node, nodes[i]), res[i]); \
+      BOOST_CHECK_EQUAL(node_comparison(nodes[i], node), !res[i]); \
+    }
+
+#define CHECK_CIRCLE(circle, c_x, c_y, l_x) \
+    BOOST_CHECK_EQUAL(ulp_cmp(c1.x(), c_x, 10), ulp_comparison<double>::EQUAL); \
+    BOOST_CHECK_EQUAL(ulp_cmp(c1.y(), c_y, 10), ulp_comparison<double>::EQUAL); \
+    BOOST_CHECK_EQUAL(ulp_cmp(c1.lower_x(), l_x, 10), ulp_comparison<double>::EQUAL)
+
+#define CHECK_CIRCLE_EXISTENCE(s1, s2, s3, RES) \
+  { circle_type c1; \
+    BOOST_CHECK_EQUAL(lazy_predicate(s1, s2, s3, c1), RES); }
+
+#define CHECK_CIRCLE_FORMATION_PREDICATE(s1, s2, s3, c_x, c_y, l_x) \
+  { circle_type c1, c2; \
+    BOOST_CHECK_EQUAL(mp_predicate(s1, s2, s3, c1), true); \
+    BOOST_CHECK_EQUAL(lazy_predicate(s1, s2, s3, c2), true); \
+    CHECK_CIRCLE(c1, c_x, c_y, l_x); \
+    CHECK_CIRCLE(c2, c_x, c_y, l_x); }
+
+BOOST_AUTO_TEST_CASE(orientation_test) {
+  int min_int = std::numeric_limits<int>::min();
+  int max_int = std::numeric_limits<int>::max();
+  point_type point1(min_int, min_int);
+  point_type point2(0, 0);
+  point_type point3(max_int, max_int);
+  point_type point4(min_int, max_int);
+  point_type point5(max_int-1, max_int);
+  CHECK_ORIENTATION(point1, point2, point3, VP::ot::COLLINEAR, VP::ot::COLLINEAR);
+  CHECK_ORIENTATION(point1, point4, point3, VP::ot::RIGHT, VP::ot::LEFT);
+  CHECK_ORIENTATION(point1, point5, point3, VP::ot::RIGHT, VP::ot::LEFT);
+}
+
+BOOST_AUTO_TEST_CASE(event_comparison_test1) {
+  site_type site(1, 2);
+  CHECK_EVENT_COMPARISON(site, site_type(0, 2), false, true);
+  CHECK_EVENT_COMPARISON(site, site_type(1, 3), true, false);
+  CHECK_EVENT_COMPARISON(site, site_type(1, 2), false, false);
+}
+
+BOOST_AUTO_TEST_CASE(event_comparison_test2) {
+  site_type site(0, 0, 0, 2);
+  CHECK_EVENT_COMPARISON(site, site_type(0, 2), true, false);
+  CHECK_EVENT_COMPARISON(site, site_type(0, 0), false, true);
+  CHECK_EVENT_COMPARISON(site, site_type(0, -2, 0, -1), false, true);
+  CHECK_EVENT_COMPARISON(site, site_type(0, -2, 1, 1), true, false);
+  CHECK_EVENT_COMPARISON(site, site_type(0, 0, 1, 1), true, false);
+}
+
+BOOST_AUTO_TEST_CASE(event_comparison_test3) {
+  site_type site(0, 0, 10, 10);
+  CHECK_EVENT_COMPARISON(site, site_type(0, 0), false, true);
+  CHECK_EVENT_COMPARISON(site, site_type(0, -1), false, true);
+  CHECK_EVENT_COMPARISON(site, site_type(0, 1), false, true);
+  CHECK_EVENT_COMPARISON(site, site_type(0, 1, 0, 10), false, true);
+  CHECK_EVENT_COMPARISON(site, site_type(0, -10, 0, -1), false, true);
+  CHECK_EVENT_COMPARISON(site, site_type(0, 0, 10, 9), true, false);
+  CHECK_EVENT_COMPARISON(site, site_type(0, 0, 9, 10), false, true);
+}
+
+BOOST_AUTO_TEST_CASE(event_comparison_test4) {
+  circle_type circle(1, 2, 3);
+  CHECK_EVENT_COMPARISON(circle, circle_type(1, 2, 3), false, false);
+  CHECK_EVENT_COMPARISON(circle, circle_type(1, 3, 3), true, false);
+  CHECK_EVENT_COMPARISON(circle, circle_type(1, 2, 4), true, false);
+  CHECK_EVENT_COMPARISON(circle, circle_type(0, 2, 2), false, true);
+  CHECK_EVENT_COMPARISON(circle, circle_type(-1, 2, 3), false, false);
+}
+
+BOOST_AUTO_TEST_CASE(event_comparison_test5) {
+  circle_type circle(1, 2, 3);
+  CHECK_EVENT_COMPARISON(circle, site_type(0, 100), false, true);
+  CHECK_EVENT_COMPARISON(circle, site_type(3, 0), false, true);
+  CHECK_EVENT_COMPARISON(circle, site_type(3, 2), false, false);
+  CHECK_EVENT_COMPARISON(circle, site_type(3, 3), true, false);
+  CHECK_EVENT_COMPARISON(circle, site_type(4, 2), true, false);
+}
+
+BOOST_AUTO_TEST_CASE(distance_predicate_test1) {
+  site_type site1(-5, 0);
+  site_type site2(-8, 9);
+  site_type site3(-2, 1);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, 5), false);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site_type(0, 5), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, 4), false);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site_type(0, 4), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, 6), true);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site_type(0, 6), true);
+}
+
+BOOST_AUTO_TEST_CASE(distance_predicate_test2) {
+  site_type site1(-4, 0, -4, 20);
+  site_type site2(-2, 10);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, 11), false);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, 9), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, 11), true);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, 9), true);
+}
+
+BOOST_AUTO_TEST_CASE(disntace_predicate_test3) {
+  site_type site1(-5, 5, 2, -2);
+  site1.inverse();
+  site_type site2(-2, 4);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, -1), false);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, -1), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, 1), false);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, 1), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, 4), true);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, 4), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, 5), true);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, 5), false);
+}
+
+BOOST_AUTO_TEST_CASE(distance_predicate_test4) {
+  site_type site1(-5, 5, 2, -2);
+  site_type site2(-2, -4);
+  site_type site3(-4, 1);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, 1), true);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, 1), true);
+  CHECK_DISTANCE_PREDICATE(site1, site3, site_type(0, 1), true);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site_type(0, 1), true);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, -2), true);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, -2), false);
+  CHECK_DISTANCE_PREDICATE(site1, site3, site_type(0, -2), true);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site_type(0, -2), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, -8), true);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, -8), false);
+  CHECK_DISTANCE_PREDICATE(site1, site3, site_type(0, -8), true);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site_type(0, -8), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(0, -9), true);
+  CHECK_DISTANCE_PREDICATE(site2, site1, site_type(0, -9), false);
+  CHECK_DISTANCE_PREDICATE(site1, site3, site_type(0, -9), true);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site_type(0, -9), false);
+}
+
+BOOST_AUTO_TEST_CASE(disntace_predicate_test5) {
+  site_type site1(-5, 5, 2, -2);
+  site_type site2 = site1;
+  site2.inverse();
+  site_type site3(-2, 4);
+  site_type site4(-2, -4);
+  site_type site5(-4, 1);
+  CHECK_DISTANCE_PREDICATE(site3, site2, site_type(0, 1), false);
+  CHECK_DISTANCE_PREDICATE(site3, site2, site_type(0, 4), false);
+  CHECK_DISTANCE_PREDICATE(site3, site2, site_type(0, 5), false);
+  CHECK_DISTANCE_PREDICATE(site3, site2, site_type(0, 7), true);
+  CHECK_DISTANCE_PREDICATE(site4, site1, site_type(0, -2), false);
+  CHECK_DISTANCE_PREDICATE(site5, site1, site_type(0, -2), false);
+  CHECK_DISTANCE_PREDICATE(site4, site1, site_type(0, -8), false);
+  CHECK_DISTANCE_PREDICATE(site5, site1, site_type(0, -8), false);
+  CHECK_DISTANCE_PREDICATE(site4, site1, site_type(0, -9), false);
+  CHECK_DISTANCE_PREDICATE(site5, site1, site_type(0, -9), false);
+  CHECK_DISTANCE_PREDICATE(site4, site1, site_type(0, -18), false);
+  CHECK_DISTANCE_PREDICATE(site5, site1, site_type(0, -18), false);
+  CHECK_DISTANCE_PREDICATE(site4, site1, site_type(0, -1), true);
+  CHECK_DISTANCE_PREDICATE(site5, site1, site_type(0, -1), true);
+}
+
+BOOST_AUTO_TEST_CASE(distance_predicate_test6) {
+  site_type site1(-5, 0, 2, 7);
+  site_type site2 = site1;
+  site2.inverse();
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(2, 7), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(1, 5), false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(-1, 5), true);
+}
+
+BOOST_AUTO_TEST_CASE(distance_predicate_test7) {
+  site_type site1(-5, 5, 2, -2);
+  site1.inverse();
+  site_type site2(-5, 5, 0, 6);
+  site_type site3(-2, 4, 0, 4);
+  site_type site4(0, 2);
+  site_type site5(0, 5);
+  site_type site6(0, 6);
+  site_type site7(0, 8);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site4, false);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site5, true);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site6, true);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site7, true);
+  CHECK_DISTANCE_PREDICATE(site1, site3, site4, false);
+  CHECK_DISTANCE_PREDICATE(site1, site3, site5, true);
+  CHECK_DISTANCE_PREDICATE(site1, site3, site6, true);
+  CHECK_DISTANCE_PREDICATE(site1, site3, site7, true);
+  site3.inverse();
+  CHECK_DISTANCE_PREDICATE(site3, site1, site4, false);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site5, false);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site6, false);
+  CHECK_DISTANCE_PREDICATE(site3, site1, site7, true);
+}
+
+BOOST_AUTO_TEST_CASE(distatnce_predicate_test8) {
+  site_type site1(-5, 3, -2, 2);
+  site1.inverse();
+  site_type site2(-5, 5, -2, 2);
+  CHECK_DISTANCE_PREDICATE(site1, site2, site_type(-4, 2), false);
+}
+
+BOOST_AUTO_TEST_CASE(node_comparison_test1) {
+  beach_line_type beach_line;
+  site_type site1(0, 0);
+  site1.index(0);
+  site_type site2(0, 2);
+  site2.index(1);
+  site_type site3(1, 0);
+  site3.index(2);
+  beach_line[key_type(site1, site2)] = 2;
+  beach_line[key_type(site1, site3)] = 0;
+  beach_line[key_type(site3, site1)] = 1;
+  int cur_index = 0;
+  for (bieach_line_iterator it = beach_line.begin();
+       it != beach_line.end(); ++it, ++cur_index) {
+    BOOST_CHECK_EQUAL(it->second, cur_index);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(node_comparison_test2) {
+  beach_line_type beach_line;
+  site_type site1(0, 1);
+  site1.index(0);
+  site_type site2(2, 0);
+  site2.index(1);
+  site_type site3(2, 4);
+  site3.index(2);
+  beach_line[key_type(site1, site2)] = 0;
+  beach_line[key_type(site2, site1)] = 1;
+  beach_line[key_type(site1, site3)] = 2;
+  beach_line[key_type(site3, site1)] = 3;
+  int cur_index = 0;
+  for (bieach_line_iterator it = beach_line.begin();
+       it != beach_line.end(); ++it, ++cur_index) {
+    BOOST_CHECK_EQUAL(it->second, cur_index);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(node_comparison_test3) {
+  key_type node(site_type(1, 0).index(1), site_type(0, 2).index(0));
+  key_type nodes[] = {
+    key_type(site_type(2, -10).index(2)),
+    key_type(site_type(2, -1).index(2)),
+    key_type(site_type(2, 0).index(2)),
+    key_type(site_type(2, 1).index(2)),
+    key_type(site_type(2, 2).index(2)),
+    key_type(site_type(2, 3).index(2)),
+  };
+  bool res[] = {false, false, false, false, true, true};
+  CHECK_NODE_COMPARISON(node, nodes, res, 6);
+}
+
+BOOST_AUTO_TEST_CASE(node_comparison_test4) {
+  key_type node(site_type(0, 1).index(0), site_type(1, 0).index(1));
+  key_type nodes[] = {
+    key_type(site_type(2, -3).index(2)),
+    key_type(site_type(2, -2).index(2)),
+    key_type(site_type(2, -1).index(2)),
+    key_type(site_type(2, 0).index(2)),
+    key_type(site_type(2, 1).index(2)),
+    key_type(site_type(2, 3).index(2)),
+  };
+  bool res[] = {false, true, true, true, true, true};
+  CHECK_NODE_COMPARISON(node, nodes, res, 6);
+}
+
+BOOST_AUTO_TEST_CASE(node_comparison_test5) {
+  key_type node(site_type(0, 0).index(0), site_type(1, 2).index(1));
+  key_type nodes[] = {
+    key_type(site_type(2, -10).index(2)),
+    key_type(site_type(2, 0).index(2)),
+    key_type(site_type(2, 1).index(2)),
+    key_type(site_type(2, 2).index(2)),
+    key_type(site_type(2, 5).index(2)),
+    key_type(site_type(2, 20).index(2)),
+  };
+  bool res[] = {false, false, true, true, true, true};
+  CHECK_NODE_COMPARISON(node, nodes, res, 6);
+}
+
+BOOST_AUTO_TEST_CASE(node_comparison_test6) {
+  key_type node(site_type(1, 1).index(1), site_type(0, 0).index(0));
+  key_type nodes [] = {
+    key_type(site_type(2, -3).index(2)),
+    key_type(site_type(2, -2).index(2)),
+    key_type(site_type(2, 0).index(2)),
+    key_type(site_type(2, 1).index(2)),
+    key_type(site_type(2, 2).index(2)),
+    key_type(site_type(2, 3).index(2)),
+    key_type(site_type(2, 5).index(2)),
+  };
+  bool res[] = {false, false, false, false, false, false, true};
+  CHECK_NODE_COMPARISON(node, nodes, res, 7);
+}
+
+BOOST_AUTO_TEST_CASE(node_comparison_test7) {
+  key_type node(site_type(0, 0).index(0), site_type(0, 2).index(1));
+  key_type nodes[] = {
+    key_type(site_type(1, 0).index(2)),
+    key_type(site_type(1, 1).index(2)),
+    key_type(site_type(1, 2).index(2)),
+  };
+  bool res[] = {false, false, true};
+  CHECK_NODE_COMPARISON(node, nodes, res, 3);
+}
+
+BOOST_AUTO_TEST_CASE(node_comparison_test8) {
+  key_type node(site_type(0, 0).index(0), site_type(1, 1).index(2));
+  key_type nodes[] = {
+    key_type(site_type(1, 0).index(1)),
+    key_type(site_type(1, 1).index(2)),
+    key_type(site_type(1, 2).index(3)),
+    key_type(site_type(1, 1).index(2), site_type(0, 0).index(0)),
+  };
+  bool res[] = {false, true, true, true};
+  CHECK_NODE_COMPARISON(node, nodes, res, 4);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test1) {
+  site_type site1(0, 0);
+  site_type site2(-8, 0);
+  site_type site3(0, 6);
+  CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, -4.0, 3.0, 1.0);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test2) {
+  int min_int = std::numeric_limits<int>::min();
+  int max_int = std::numeric_limits<int>::max();
+  site_type site1(min_int, min_int);
+  site_type site2(min_int, max_int);
+  site_type site3(max_int-1, max_int-1);
+  site_type site4(max_int, max_int);
+  CHECK_CIRCLE_EXISTENCE(site1, site2, site4, true);
+  CHECK_CIRCLE_EXISTENCE(site1, site3, site4, false);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test3) {
+  site_type site1(-4, 0);
+  site_type site2(0, 4);
+  site_type site3(site1.point0(), site2.point0());
+  CHECK_CIRCLE_EXISTENCE(site1, site3, site2, false);
+  site_type site4(-2, 0);
+  site_type site5(0, 2);
+  CHECK_CIRCLE_EXISTENCE(site3, site4, site5, false);
+  CHECK_CIRCLE_EXISTENCE(site4, site5, site3, false);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test4) {
+  site_type site1(-4, 0, -4, 20);
+  site_type site2(-2, 10);
+  site_type site3(4, 10);
+  CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, 1.0, 6.0, 6.0);
+  CHECK_CIRCLE_FORMATION_PREDICATE(site3, site2, site1, 1.0, 14.0, 6.0);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test5) {
+  site_type site1(1, 0, 7, 0);
+  site1.inverse();
+  site_type site2(-2, 4, 10, 4);
+  site_type site3(6, 2);
+  site_type site4(1, 0);
+  CHECK_CIRCLE_FORMATION_PREDICATE(site3, site1, site2, 4.0, 2.0, 6.0);
+  CHECK_CIRCLE_FORMATION_PREDICATE(site4, site2, site1, 1.0, 2.0, 3.0);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test6) {
+  site_type site1(-1, 2, 8, -10);
+  site1.inverse();
+  site_type site2(-1, 0, 8, 12);
+  site_type site3(1, 1);
+  CHECK_CIRCLE_FORMATION_PREDICATE(site3, site2, site1, 6.0, 1.0, 11.0);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test7) {
+  site_type site1(1, 0, 6, 0);
+  site1.inverse();
+  site_type site2(-6, 4, 0, 12);
+  site_type site3(1, 0);
+  CHECK_CIRCLE_FORMATION_PREDICATE(site3, site2, site1, 1.0, 5.0, 6.0);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test8) {
+  site_type site1(1, 0, 5, 0);
+  site1.inverse();
+  site_type site2(0, 12, 8, 6);
+  site_type site3(1, 0);
+  CHECK_CIRCLE_FORMATION_PREDICATE(site3, site2, site1, 1.0, 5.0, 6.0);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test9) {
+  site_type site1(0, 0, 4, 0);
+  site_type site2(0, 0, 0, 4);
+  site_type site3(0, 4, 4, 4);
+  site1.inverse();
+  CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, 2.0, 2.0, 4.0);
+}
+
+BOOST_AUTO_TEST_CASE(circle_formation_predicate_test10) {
+  site_type site1(1, 0, 41, 30);
+  site_type site2(-39, 30, 1, 60);
+  site_type site3(1, 60, 41, 30);
+  site1.inverse();
+  CHECK_CIRCLE_FORMATION_PREDICATE(site1, site2, site3, 1.0, 30.0, 25.0);
+}
Added: trunk/libs/polygon/test/voronoi_robust_fpt_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/polygon/test/voronoi_robust_fpt_test.cpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,342 @@
+// Boost.Polygon library voronoi_robust_fpt_test.cpp file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <cmath>
+#include <ctime>
+
+#define BOOST_TEST_MODULE voronoi_robust_fpt_test
+#include <boost/mpl/list.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/test/test_case_template.hpp>
+
+#include <boost/polygon/detail/voronoi_ctypes.hpp>
+#include <boost/polygon/detail/voronoi_robust_fpt.hpp>
+using namespace boost::polygon::detail;
+
+typedef robust_fpt<double> rfpt_type;
+typedef type_converter_fpt to_fpt_type;
+typedef type_converter_efpt to_efpt_type;
+type_converter_fpt to_fpt;
+
+BOOST_AUTO_TEST_CASE(robust_fpt_constructors_test1) {
+  rfpt_type a = rfpt_type();
+  BOOST_CHECK_EQUAL(a.fpv(), 0.0);
+  BOOST_CHECK_EQUAL(a.re(), 0.0);
+  BOOST_CHECK_EQUAL(a.ulp(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_fpt_constructors_test2) {
+  rfpt_type a(10.0, 1.0);
+  BOOST_CHECK_EQUAL(a.fpv(), 10.0);
+  BOOST_CHECK_EQUAL(a.re(), 1.0);
+  BOOST_CHECK_EQUAL(a.ulp(), 1.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_fpt_constructors_test3) {
+  rfpt_type a(10.0);
+  BOOST_CHECK_EQUAL(a.fpv(), 10.0);
+  BOOST_CHECK_EQUAL(a.re(), 0.0);
+  BOOST_CHECK_EQUAL(a.ulp(), 0.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_fpt_constructors_test4) {
+  rfpt_type a(10.0, 3.0);
+  BOOST_CHECK_EQUAL(a.fpv(), 10.0);
+  BOOST_CHECK_EQUAL(a.re(), 3.0);
+  BOOST_CHECK_EQUAL(a.ulp(), 3.0);
+
+  rfpt_type b(10.0, 2.75);
+  BOOST_CHECK_EQUAL(b.fpv(), 10.0);
+  BOOST_CHECK_EQUAL(b.re(), 2.75);
+  BOOST_CHECK_EQUAL(b.ulp(), 2.75);
+}
+
+BOOST_AUTO_TEST_CASE(robust_fpt_sum_test1) {
+  rfpt_type a(2.0, 5.0);
+  rfpt_type b(3.0, 4.0);
+  rfpt_type c = a + b;
+  BOOST_CHECK_EQUAL(c.fpv(), 5.0);
+  BOOST_CHECK_EQUAL(c.re(), 6.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 6.0);
+
+  c += b;
+  BOOST_CHECK_EQUAL(c.fpv(), 8.0);
+  BOOST_CHECK_EQUAL(c.re(), 7.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 7.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_fpt_sum_test2) {
+  rfpt_type a(3.0, 2.0);
+  rfpt_type b(-2.0, 3.0);
+  rfpt_type c = a + b;
+  BOOST_CHECK_EQUAL(c.fpv(), 1.0);
+  BOOST_CHECK_EQUAL(c.re(), 13.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 13.0);
+
+  c += b;
+  BOOST_CHECK_EQUAL(c.fpv(), -1.0);
+  BOOST_CHECK_EQUAL(c.re(), 20.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 20.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_fpt_dif_test1) {
+  rfpt_type a(2.0, 5.0);
+  rfpt_type b(-3.0, 4.0);
+  rfpt_type c = a - b;
+  BOOST_CHECK_EQUAL(c.fpv(), 5.0);
+  BOOST_CHECK_EQUAL(c.re(), 6.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 6.0);
+
+  c -= b;
+  BOOST_CHECK_EQUAL(c.fpv(), 8.0);
+  BOOST_CHECK_EQUAL(c.re(), 7.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 7.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_fpt_dif_test2) {
+  rfpt_type a(3.0, 2.0);
+  rfpt_type b(2.0, 3.0);
+  rfpt_type c = a - b;
+  BOOST_CHECK_EQUAL(c.fpv(), 1.0);
+  BOOST_CHECK_EQUAL(c.re(), 13.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 13.0);
+
+  c -= b;
+  BOOST_CHECK_EQUAL(c.fpv(), -1.0);
+  BOOST_CHECK_EQUAL(c.re(), 20.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 20.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_fpt_mult_test3) {
+  rfpt_type a(2.0, 3.0);
+  rfpt_type b(4.0, 1.0);
+  rfpt_type c = a * b;
+  BOOST_CHECK_EQUAL(c.fpv(), 8.0);
+  BOOST_CHECK_EQUAL(c.re(), 5.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 5.0);
+
+  c *= b;
+  BOOST_CHECK_EQUAL(c.fpv(), 32.0);
+  BOOST_CHECK_EQUAL(c.re(), 7.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 7.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_fpt_div_test1) {
+  rfpt_type a(2.0, 3.0);
+  rfpt_type b(4.0, 1.0);
+  rfpt_type c = a / b;
+  BOOST_CHECK_EQUAL(c.fpv(), 0.5);
+  BOOST_CHECK_EQUAL(c.re(), 5.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 5.0);
+
+  c /= b;
+  BOOST_CHECK_EQUAL(c.fpv(), 0.125);
+  BOOST_CHECK_EQUAL(c.re(), 7.0);
+  BOOST_CHECK_EQUAL(c.ulp(), 7.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_dif_constructors_test) {
+  robust_dif<int> rd1;
+  BOOST_CHECK_EQUAL(rd1.pos(), 0);
+  BOOST_CHECK_EQUAL(rd1.neg(), 0);
+  BOOST_CHECK_EQUAL(rd1.dif(), 0);
+
+  robust_dif<int> rd2(1);
+  BOOST_CHECK_EQUAL(rd2.pos(), 1);
+  BOOST_CHECK_EQUAL(rd2.neg(), 0);
+  BOOST_CHECK_EQUAL(rd2.dif(), 1);
+
+  robust_dif<int> rd3(-1);
+  BOOST_CHECK_EQUAL(rd3.pos(), 0);
+  BOOST_CHECK_EQUAL(rd3.neg(), 1);
+  BOOST_CHECK_EQUAL(rd3.dif(), -1);
+
+  robust_dif<int> rd4(1, 2);
+  BOOST_CHECK_EQUAL(rd4.pos(), 1);
+  BOOST_CHECK_EQUAL(rd4.neg(), 2);
+  BOOST_CHECK_EQUAL(rd4.dif(), -1);
+}
+
+BOOST_AUTO_TEST_CASE(robust_dif_operators_test1) {
+  robust_dif<int> a(5, 2), b(1, 10);
+  int dif_a = a.dif();
+  int dif_b = b.dif();
+  robust_dif<int> sum = a + b;
+  robust_dif<int> dif = a - b;
+  robust_dif<int> mult = a * b;
+  robust_dif<int> umin = -a;
+  BOOST_CHECK_EQUAL(sum.dif(), dif_a + dif_b);
+  BOOST_CHECK_EQUAL(dif.dif(), dif_a - dif_b);
+  BOOST_CHECK_EQUAL(mult.dif(), dif_a * dif_b);
+  BOOST_CHECK_EQUAL(umin.dif(), -dif_a);
+}
+
+BOOST_AUTO_TEST_CASE(robust_dif_operators_test2) {
+  robust_dif<int> a(5, 2);
+  for (int b = -3; b <= 3; b += 6) {
+    int dif_a = a.dif();
+    int dif_b = b;
+    robust_dif<int> sum = a + b;
+    robust_dif<int> dif = a - b;
+    robust_dif<int> mult = a * b;
+    robust_dif<int> div = a / b;
+    BOOST_CHECK_EQUAL(sum.dif(), dif_a + dif_b);
+    BOOST_CHECK_EQUAL(dif.dif(), dif_a - dif_b);
+    BOOST_CHECK_EQUAL(mult.dif(), dif_a * dif_b);
+    BOOST_CHECK_EQUAL(div.dif(), dif_a / dif_b);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(robust_dif_operators_test3) {
+  robust_dif<int> b(5, 2);
+  for (int a = -3; a <= 3; a += 6) {
+    int dif_a = a;
+    int dif_b = b.dif();
+    robust_dif<int> sum = a + b;
+    robust_dif<int> dif = a - b;
+    robust_dif<int> mult = a * b;
+    BOOST_CHECK_EQUAL(sum.dif(), dif_a + dif_b);
+    BOOST_CHECK_EQUAL(dif.dif(), dif_a - dif_b);
+    BOOST_CHECK_EQUAL(mult.dif(), dif_a * dif_b);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(robust_dif_operators_test4) {
+  std::vector< robust_dif<int> > a4(4, robust_dif<int>(5, 2));
+  std::vector< robust_dif<int> > b4(4, robust_dif<int>(1, 2));
+  std::vector< robust_dif<int> > c4 = a4;
+  c4[0] += b4[0];
+  c4[1] -= b4[1];
+  c4[2] *= b4[2];
+  BOOST_CHECK_EQUAL(c4[0].dif(), a4[0].dif() + b4[0].dif());
+  BOOST_CHECK_EQUAL(c4[1].dif(), a4[1].dif() - b4[1].dif());
+  BOOST_CHECK_EQUAL(c4[2].dif(), a4[2].dif() * b4[2].dif());
+  a4[0] += b4[0].dif();
+  a4[1] -= b4[1].dif();
+  a4[2] *= b4[2].dif();
+  a4[3] /= b4[3].dif();
+  BOOST_CHECK_EQUAL(c4[0].dif(), a4[0].dif());
+  BOOST_CHECK_EQUAL(c4[1].dif(), a4[1].dif());
+  BOOST_CHECK_EQUAL(c4[2].dif(), a4[2].dif());
+  BOOST_CHECK_EQUAL(c4[3].dif() / b4[3].dif(), a4[3].dif());
+}
+
+BOOST_AUTO_TEST_CASE(robust_sqrt_expr_test1) {
+  robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+  int32 A[1] = {10};
+  int32 B[1] = {100};
+  BOOST_CHECK_EQUAL(sqrt_expr.eval1(A, B), 100.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_sqrt_expr_test2) {
+  robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+  int32 A[2] = {10, 30};
+  int32 B[2] = {400, 100};
+  BOOST_CHECK_EQUAL(sqrt_expr.eval2(A, B), 500.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_sqrt_expr_test3) {
+  robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+  int32 A[2] = {10, -30};
+  int32 B[2] = {400, 100};
+  BOOST_CHECK_EQUAL(sqrt_expr.eval2(A, B), -100.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_sqrt_expr_test4) {
+  robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+  int32 A[3] = {10, 30, 20};
+  int32 B[3] = {4, 1, 9};
+  BOOST_CHECK_EQUAL(sqrt_expr.eval3(A, B), 110.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_sqrt_expr_test5) {
+  robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+  int32 A[3] = {10, 30, -20};
+  int32 B[3] = {4, 1, 9};
+  BOOST_CHECK_EQUAL(sqrt_expr.eval3(A, B), -10.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_sqrt_expr_test6) {
+  robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+  int32 A[4] = {10, 30, 20, 5};
+  int32 B[4] = {4, 1, 9, 16};
+  BOOST_CHECK_EQUAL(sqrt_expr.eval4(A, B), 130.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_sqrt_expr_test7) {
+  robust_sqrt_expr<int32, fpt64, to_fpt_type> sqrt_expr;
+  int32 A[4] = {10, 30, -20, -5};
+  int32 B[4] = {4, 1, 9, 16};
+  BOOST_CHECK_EQUAL(sqrt_expr.eval4(A, B), -30.0);
+}
+
+BOOST_AUTO_TEST_CASE(robust_sqrt_expr_test8) {
+  typedef extended_int<16> eint512;
+  robust_sqrt_expr<eint512, efpt64, to_efpt_type> sqrt_expr;
+  int32 A[4] = {1000, 3000, -2000, -500};
+  int32 B[4] = {400, 100, 900, 1600};
+  eint512 AA[4], BB[4];
+  for (size_t i = 0; i < 4; ++i) {
+    AA[i] = A[i];
+    BB[i] = B[i];
+  }
+  BOOST_CHECK_EQUAL(to_fpt(sqrt_expr.eval4(AA, BB)), -30000.0);
+}
+
+template <typename _int, typename _fpt>
+class sqrt_expr_tester {
+public:
+  static const size_t MX_SQRTS = 4;
+
+  bool run() {
+    static boost::mt19937 gen(static_cast<uint32>(time(NULL)));
+    bool ret_val = true;
+    for (size_t i = 0; i < MX_SQRTS; ++i) {
+      a[i] = gen() & 1048575;
+      int64 temp = gen() & 1048575;
+      b[i] = temp * temp;
+    }
+    uint32 mask = (1 << MX_SQRTS);
+    for (size_t i = 0; i < mask; i++) {
+      fpt64 expected_val = 0.0;
+      for (size_t j = 0; j < MX_SQRTS; j++) {
+        if (i & (1 << j)) {
+          A[j] = a[j];
+          B[j] = b[j];
+          expected_val += static_cast<fpt64>(a[j]) *
+                          sqrt(static_cast<fpt64>(b[j]));
+        } else {
+          A[j] = -a[j];
+          B[j] = b[j];
+          expected_val -= static_cast<fpt64>(a[j]) *
+                          sqrt(static_cast<fpt64>(b[j]));
+        }
+      }
+      fpt64 received_val = to_fpt(sqrt_expr_.eval4(A, B));
+      ret_val &= ulp_cmp(expected_val, received_val, 25) ==
+                 ulp_comparison<fpt64>::EQUAL;
+    }
+    return ret_val;
+  }
+
+private:
+  robust_sqrt_expr<_int, _fpt, to_efpt_type> sqrt_expr_;
+  ulp_comparison<fpt64> ulp_cmp;
+  _int A[MX_SQRTS];
+  _int B[MX_SQRTS];
+  int64 a[MX_SQRTS];
+  int64 b[MX_SQRTS];
+};
+
+BOOST_AUTO_TEST_CASE(mpz_sqrt_evaluator_test) {
+  typedef extended_int<16> eint512;
+  sqrt_expr_tester<eint512, efpt64> tester;
+  for (int i = 0; i < 2000; ++i)
+    BOOST_CHECK(tester.run());
+}
Added: trunk/libs/polygon/test/voronoi_structures_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/polygon/test/voronoi_structures_test.cpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,133 @@
+// Boost.Polygon library voronoi_structures_test.cpp file
+
+//          Copyright Andrii Sydorchuk 2010-2012.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#define BOOST_TEST_MODULE voronoi_structures_test
+
+#include <boost/test/test_case_template.hpp>
+#include <boost/polygon/detail/voronoi_structures.hpp>
+using namespace boost::polygon::detail;
+
+typedef point_2d<int> point_type;
+typedef site_event<int> site_type;
+typedef circle_event<int> circle_type;
+typedef ordered_queue<int, std::greater<int> > ordered_queue_type;
+typedef beach_line_node_key<int> node_key_type;
+typedef beach_line_node_data<int, int> node_data_type;
+
+BOOST_AUTO_TEST_CASE(point_2d_test1) {
+  point_type p(1, 2);
+  BOOST_CHECK_EQUAL(p.x(), 1);
+  BOOST_CHECK_EQUAL(p.y(), 2);
+  p.x(3);
+  BOOST_CHECK_EQUAL(p.x(), 3);
+  p.y(4);
+  BOOST_CHECK_EQUAL(p.y(), 4);
+}
+
+BOOST_AUTO_TEST_CASE(site_event_test2) {
+  site_type s(1, 2);
+  BOOST_CHECK(s.x0() == s.x1() && s.x1() == 1);
+  BOOST_CHECK(s.y0() == s.y1() && s.y1() == 2);
+  BOOST_CHECK(s.index() == 0);
+  BOOST_CHECK(!s.is_segment());
+  BOOST_CHECK(!s.is_inverse());
+  s.index(1);
+  BOOST_CHECK(s.index() == 1);
+  BOOST_CHECK(!s.is_inverse());
+}
+
+BOOST_AUTO_TEST_CASE(site_event_test3) {
+  site_type s(1, 2, 3, 4);
+  BOOST_CHECK(s.x0(true) == 1 && s.x0() == 1);
+  BOOST_CHECK(s.y0(true) == 2 && s.y0() == 2);
+  BOOST_CHECK(s.x1(true) == 3 && s.x1() == 3);
+  BOOST_CHECK(s.y1(true) == 4 && s.y1() == 4);
+  BOOST_CHECK(s.index() == 0);
+  BOOST_CHECK(s.is_segment());
+  BOOST_CHECK(!s.is_inverse());
+  s.inverse();
+  BOOST_CHECK(s.x1(true) == 1 && s.x0() == 1);
+  BOOST_CHECK(s.y1(true) == 2 && s.y0() == 2);
+  BOOST_CHECK(s.x0(true) == 3 && s.x1() == 3);
+  BOOST_CHECK(s.y0(true) == 4 && s.y1() == 4);
+  BOOST_CHECK(s.is_inverse());
+}
+
+BOOST_AUTO_TEST_CASE(site_event_test4) {
+  site_type s(1, 2, 3, 4);
+  s.index(27);
+  BOOST_CHECK(s.is_initial());
+  BOOST_CHECK(s.has_initial_direction());
+  BOOST_CHECK(s.index() == 27);
+  s.inverse();
+  BOOST_CHECK(!s.has_initial_direction());
+  BOOST_CHECK(s.is_initial());
+  BOOST_CHECK(s.index() == 27);
+  s.change_initial_direction();
+  BOOST_CHECK(s.has_initial_direction());
+  BOOST_CHECK(!s.is_initial());
+  BOOST_CHECK(s.index() == 27);
+}
+
+BOOST_AUTO_TEST_CASE(circle_event_test) {
+  circle_type c(0, 1, 2);
+  BOOST_CHECK_EQUAL(c.x(), 0);
+  BOOST_CHECK_EQUAL(c.y(), 1);
+  BOOST_CHECK_EQUAL(c.lower_x(), 2);
+  BOOST_CHECK_EQUAL(c.lower_y(), 1);
+  BOOST_CHECK(c.is_active());
+  c.x(3);
+  c.y(4);
+  c.lower_x(5);
+  BOOST_CHECK_EQUAL(c.x(), 3);
+  BOOST_CHECK_EQUAL(c.y(), 4);
+  BOOST_CHECK_EQUAL(c.lower_x(), 5);
+  BOOST_CHECK_EQUAL(c.lower_y(), 4);
+  c.deactivate();
+  BOOST_CHECK(!c.is_active());
+}
+
+BOOST_AUTO_TEST_CASE(ordered_queue_test) {
+  ordered_queue_type q;
+  BOOST_CHECK(q.empty());
+  std::vector<int*> vi;
+  for (int i = 0; i < 20; ++i)
+    vi.push_back(&q.push(i));
+  for (int i = 0; i < 20; ++i)
+    *vi[i] <<= 1;
+  BOOST_CHECK(!q.empty());
+  for (int i = 0; i < 20; ++i, q.pop())
+    BOOST_CHECK_EQUAL(q.top(), i << 1);
+  BOOST_CHECK(q.empty());
+}
+
+BOOST_AUTO_TEST_CASE(beach_line_node_key_test) {
+  node_key_type key(1);
+  BOOST_CHECK_EQUAL(key.left_site(), 1);
+  BOOST_CHECK_EQUAL(key.right_site(), 1);
+  key.left_site(2);
+  BOOST_CHECK_EQUAL(key.left_site(), 2);
+  BOOST_CHECK_EQUAL(key.right_site(), 1);
+  key.right_site(3);
+  BOOST_CHECK_EQUAL(key.left_site(), 2);
+  BOOST_CHECK_EQUAL(key.right_site(), 3);
+}
+
+BOOST_AUTO_TEST_CASE(beach_line_node_data_test) {
+  node_data_type node_data(NULL);
+  BOOST_CHECK_EQUAL(node_data.edge() == NULL, true);
+  BOOST_CHECK_EQUAL(node_data.circle_event() == NULL, true);
+  int data = 4;
+  node_data.circle_event(&data);
+  BOOST_CHECK_EQUAL(node_data.edge() == NULL, true);
+  BOOST_CHECK_EQUAL(node_data.circle_event() == &data, true);
+  node_data.edge(&data);
+  BOOST_CHECK_EQUAL(node_data.edge() == &data, true);
+  BOOST_CHECK_EQUAL(node_data.circle_event() == &data, true);
+}
Added: trunk/libs/polygon/test/voronoi_test_helper.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/polygon/test/voronoi_test_helper.hpp	2012-05-05 10:29:08 EDT (Sat, 05 May 2012)
@@ -0,0 +1,272 @@
+// Boost.Polygon library voronoi_test_helper.hpp file 
+
+//          Copyright Andrii Sydorchuk 2010-2011.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef VORONOI_TEST_HELPER
+#define VORONOI_TEST_HELPER
+
+#include <iostream>
+#include <iterator>
+#include <fstream>
+#include <map>
+#include <vector>
+
+#include <boost/polygon/polygon.hpp>
+using namespace boost::polygon;
+
+namespace voronoi_test_helper {
+
+enum kOrientation {
+  RIGHT = -1,
+  COLLINEAR = 0,
+  LEFT = 1
+};
+
+template <typename Point2D>
+kOrientation get_orientation(const Point2D &point1,
+                             const Point2D &point2,
+                             const Point2D &point3) {
+  typename Point2D::coordinate_type a = (point2.x() - point1.x()) * (point3.y() - point2.y());
+  typename Point2D::coordinate_type b = (point2.y() - point1.y()) * (point3.x() - point2.x());
+  if (a == b)
+    return COLLINEAR;
+  return (a < b) ? RIGHT : LEFT;
+}
+
+template <typename Output>
+bool verify_half_edge_orientation(const Output &output) {
+  typedef typename Output::point_type point_type;
+  typename Output::const_edge_iterator edge_it;
+  for (edge_it = output.edges().begin(); 
+       edge_it != output.edges().end(); edge_it++) {
+    if (edge_it->is_finite()) {
+      const point_type &site_point = edge_it->cell()->point0();
+      const point_type &start_point = edge_it->vertex0()->vertex();
+      const point_type &end_point = edge_it->vertex1()->vertex();
+      if (get_orientation(start_point, end_point, site_point) != LEFT)
+        return false;
+    }
+  }
+  return true;
+}
+
+template <typename Output>
+bool verify_cell_convexity(const Output &output) {
+  typedef typename Output::point_type point_type;
+  typename Output::const_cell_iterator cell_it;
+  for (cell_it = output.cells().begin();
+       cell_it != output.cells().end(); cell_it++) {
+    const typename Output::edge_type *edge = cell_it->incident_edge();
+    if (edge)
+      do {
+        if (edge->next()->prev() != edge)
+          return false;
+        if (edge->cell() != &(*cell_it))
+          return false;
+        if (edge->vertex0() != NULL &&
+            edge->vertex1() != NULL &&
+            edge->vertex1() == edge->next()->vertex0() &&
+            edge->next()->vertex1() != NULL) {
+          const point_type &vertex1 = edge->vertex0()->vertex();
+          const point_type &vertex2 = edge->vertex1()->vertex();
+          const point_type &vertex3 = edge->next()->vertex1()->vertex();
+          if (get_orientation(vertex1, vertex2, vertex3) != LEFT)
+            return false;
+        }
+        edge = edge->next();
+      } while(edge != cell_it->incident_edge());
+  }
+  return true;
+}
+
+template <typename Output>
+bool verify_incident_edges_ccw_order(const Output &output) {
+  typedef typename Output::point_type point_type;
+  typedef typename Output::edge_type voronoi_edge_type;
+  typename Output::const_vertex_iterator vertex_it;
+  for (vertex_it = output.vertices().begin();
+     vertex_it != output.vertices().end(); vertex_it++) {
+    if (vertex_it->is_degenerate())
+      continue;
+    const voronoi_edge_type *edge = vertex_it->incident_edge();
+    do {
+      const voronoi_edge_type *edge_next1 = edge->rot_next();
+      const voronoi_edge_type *edge_next2 = edge_next1->rot_next();
+      const point_type &site1 = edge->cell()->point0();
+      const point_type &site2 = edge_next1->cell()->point0();
+      const point_type &site3 = edge_next2->cell()->point0();
+
+      if (get_orientation(site1, site2, site3) != LEFT)
+        return false;
+
+      edge = edge->rot_next();
+    } while (edge != vertex_it->incident_edge());
+  }
+  return true;
+}
+
+template <typename P>
+struct cmp {
+  bool operator()(const P& p1, const P& p2) const {
+    if (p1.x() != p2.x()) 
+      return p1.x() < p2.x();
+    return p1.y() < p2.y();
+  }
+};
+
+template <typename Output>
+bool verfiy_no_line_edge_intersections(const Output &output) {
+  // Create map from edges with first point less than the second one.
+  // Key is the first point of the edge, value is a vector of second points
+  // with the same first point.
+  typedef typename Output::point_type point_type;
+  cmp<point_type> comparator;
+  std::map< point_type, std::vector<point_type>, cmp<point_type> > edge_map;
+  typename Output::const_edge_iterator edge_it;
+  for (edge_it = output.edges().begin();
+       edge_it != output.edges().end(); edge_it++) {
+    if (edge_it->is_finite()) {
+        const point_type &vertex0 = edge_it->vertex0()->vertex();
+        const point_type &vertex1 = edge_it->vertex1()->vertex();
+      if (comparator(vertex0, vertex1))
+        edge_map[vertex0].push_back(vertex1);
+    }
+  }
+  return !intersection_check(edge_map);
+}
+
+template <typename Point2D>
+bool intersection_check(const std::map< Point2D, std::vector<Point2D>, cmp<Point2D> > &edge_map) {
+  // Iterate over map of edges and check if there are any intersections.
+  // All the edges are stored by the low x value. That's why we iterate
+  // left to right checking for intersections between all pairs of edges
+  // that overlap in the x dimension.
+  // Complexity. Approximately N*sqrt(N). Worst case N^2.
+  typedef Point2D point_type;
+  typedef typename point_type::coordinate_type coordinate_type;
+  typedef typename std::map< point_type, std::vector<point_type>, cmp<Point2D> >::const_iterator
+      edge_map_iterator;
+  typedef typename std::vector<point_type>::size_type size_type;
+  edge_map_iterator edge_map_it1, edge_map_it2, edge_map_it_bound;
+  for (edge_map_it1 = edge_map.begin();
+       edge_map_it1 != edge_map.end(); edge_map_it1++) {
+    const point_type &point1 = edge_map_it1->first;
+    for (size_type i = 0; i < edge_map_it1->second.size(); i++) {
+      const point_type &point2 = edge_map_it1->second[i];
+      coordinate_type min_y1 = std::min(point1.y(), point2.y());
+      coordinate_type max_y1 = std::max(point1.y(), point2.y());
+
+      // Find the first edge with greater or equal first point.
+      edge_map_it_bound = edge_map.lower_bound(point2);
+
+      edge_map_it2 = edge_map_it1;
+      edge_map_it2++;
+      for (; edge_map_it2 != edge_map_it_bound; edge_map_it2++) {
+        const point_type &point3 = edge_map_it2->first;
+        for (size_type j = 0; j < edge_map_it2->second.size(); j++) {
+          const point_type &point4 = edge_map_it2->second[j];
+          coordinate_type min_y2 = std::min(point3.y(), point4.y());
+          coordinate_type max_y2 = std::max(point3.y(), point4.y());
+          
+          // In most cases it is enought to make 
+          // simple intersection check in the y dimension.
+          if (!(max_y1 > min_y2 && max_y2 > min_y1))
+            continue;
+
+          // Intersection check.
+          if (get_orientation(point1, point2, point3) *
+              get_orientation(point1, point2, point4) == RIGHT &&
+              get_orientation(point3, point4, point1) *
+              get_orientation(point3, point4, point2) == RIGHT)
+            return true;
+        }
+      }
+    }
+  }
+  return false;
+}
+
+enum kVerification {
+  HALF_EDGE_ORIENTATION = 1,
+  CELL_CONVEXITY = 2,
+  INCIDENT_EDGES_CCW_ORDER = 4,
+  NO_HALF_EDGE_INTERSECTIONS = 8,
+  FAST_VERIFICATION = 7,
+  COMPLETE_VERIFICATION = 15
+};
+
+template <typename Output>
+bool verify_output(const Output &output, kVerification mask) {
+  bool result = true;
+  if (mask & HALF_EDGE_ORIENTATION)
+    result &= verify_half_edge_orientation(output);
+  if (mask & CELL_CONVEXITY)
+    result &= verify_cell_convexity(output);
+  if (mask & INCIDENT_EDGES_CCW_ORDER)
+    result &= verify_incident_edges_ccw_order(output);
+  if (mask & NO_HALF_EDGE_INTERSECTIONS)
+    result &= verfiy_no_line_edge_intersections(output);
+  return result;
+}
+
+template <typename PointIterator>
+void save_points(PointIterator first, PointIterator last, const char *file_name) {
+  std::ofstream ofs(file_name);
+  ofs << std::distance(first, last) << std::endl;
+  for (PointIterator it = first; it != last; ++it) {
+    ofs << it->x() << " " << it->y() << std::endl;
+  }
+  ofs.close();
+}
+
+template <typename SegmentIterator>
+void save_segments(SegmentIterator first, SegmentIterator last, const char *file_name) {
+  std::ofstream ofs(file_name);
+  ofs << std::distance(first, last) << std::endl;
+  for (SegmentIterator it = first; it != last; ++it) {
+    ofs << it->low().x() << " " << it->low().y() << " ";
+    ofs << it->high().x() << " " << it->high().y() << std::endl;
+  }
+  ofs.close();
+}
+
+template <typename T>
+void clean_segment_set(std::vector< segment_data<T> > &data) {
+  typedef T Unit;
+  typedef typename scanline_base<Unit>::Point Point;
+  typedef typename scanline_base<Unit>::half_edge half_edge;
+  typedef int segment_id;
+  std::vector<std::pair<half_edge, segment_id> > half_edges;
+  std::vector<std::pair<half_edge, segment_id> > half_edges_out;
+  segment_id id = 0;
+  half_edges.reserve(data.size());
+  for (typename std::vector< segment_data<T> >::iterator it = data.begin(); it != data.end(); ++it) {
+    Point l = it->low();
+    Point h = it->high();
+    half_edges.push_back(std::make_pair(half_edge(l, h), id++));
+  }
+  half_edges_out.reserve(half_edges.size());
+  //apparently no need to pre-sort data when calling validate_scan
+  line_intersection<Unit>::validate_scan(half_edges_out, half_edges.begin(), half_edges.end());
+  std::vector< segment_data<T> > result;
+  result.reserve(half_edges_out.size());
+  for (std::size_t i = 0; i < half_edges_out.size(); ++i) {
+    id = half_edges_out[i].second;
+    Point l = half_edges_out[i].first.first;
+    Point h = half_edges_out[i].first.second;
+    segment_data<T> orig_seg = data[id];
+    if (orig_seg.high() < orig_seg.low())
+      std::swap(l, h);
+    result.push_back(segment_data<T>(l, h));
+  }
+  std::swap(result, data);
+}
+
+} // voronoi_test_helper
+
+#endif