+ if (size == 0)
+ {
+ empty_skyline (result);
+ return;
+ }
+ else if (size == 1)
+ {
+ single_skyline (buildings->front (), result, max_slope_);
+ return;
+ }
+
+ list<Building> right_half;
+ list<Building>::iterator i = buildings->begin ();
+
+ for (vsize s = 0; s < size/2; s++)
+ i++;
+ right_half.splice (right_half.end (), *buildings, i, buildings->end ());
+
+ list<Building> right;
+ list<Building> left;
+ internal_build_skyline (&right_half, &right);
+ internal_build_skyline (buildings, &left);
+ internal_merge_skyline (&right, &left, result);
+}
+
+Skyline::Skyline ()
+{
+ max_slope_ = 2;
+ sky_ = UP;
+ empty_skyline (&buildings_);
+}
+
+Skyline::Skyline (Direction sky)
+{
+ max_slope_ = 2;
+ sky_ = sky;
+ empty_skyline (&buildings_);
+}
+
+Skyline::Skyline (vector<Box> const &boxes, Axis a, Direction sky)
+{
+ list<Building> bldgs;
+ sky_ = sky;
+ max_slope_ = 2;
+
+ for (vsize i = 0; i < boxes.size (); i++)
+ {
+ Interval iv = boxes[i][a];
+ Real height = sky * boxes[i][other_axis (a)][sky];
+ if (!iv.is_empty () && !isinf (height) && !equal (iv[LEFT], iv[RIGHT]))
+ bldgs.push_front (Building (iv[LEFT], height, height, iv[RIGHT], max_slope_));
+ }
+ internal_build_skyline (&bldgs, &buildings_);
+ assert (is_legal_skyline ());
+}
+
+void
+Skyline::merge (Skyline const &other)
+{
+ assert (sky_ == other.sky_);
+
+ list<Building> other_bld (other.buildings_);
+ list<Building> my_bld;
+ my_bld.splice (my_bld.begin (), buildings_);
+ internal_merge_skyline (&other_bld, &my_bld, &buildings_);
+ assert (is_legal_skyline ());
+}
+
+void
+Skyline::insert (Box const &b, Axis a)
+{
+ list<Building> other_bld;
+ list<Building> my_bld;
+ Interval iv = b[a];
+ Real height = sky_ * b[other_axis (a)][sky_];
+
+ my_bld.splice (my_bld.begin (), buildings_);
+ single_skyline (Building (iv[LEFT], height, height, iv[RIGHT], max_slope_), &other_bld, max_slope_);
+ internal_merge_skyline (&other_bld, &my_bld, &buildings_);
+ assert (is_legal_skyline ());