From 71660a281bc85812708265ba7f9ce7f320af8d1a Mon Sep 17 00:00:00 2001
From: enricoturri1966 <enricoturri@seznam.cz>
Date: Wed, 19 Oct 2022 08:52:35 +0200
Subject: [PATCH 1/5] Tech ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL set as
 default

---
 src/libslic3r/Technologies.hpp    |  2 --
 src/slic3r/GUI/3DScene.cpp        | 24 +----------------
 src/slic3r/GUI/3DScene.hpp        | 15 -----------
 src/slic3r/GUI/GCodeViewer.cpp    | 10 -------
 src/slic3r/GUI/GLCanvas3D.cpp     | 45 +------------------------------
 src/slic3r/GUI/GUI_ObjectList.cpp |  6 -----
 src/slic3r/GUI/Plater.cpp         | 16 ++---------
 src/slic3r/GUI/Selection.cpp      | 32 +---------------------
 8 files changed, 5 insertions(+), 145 deletions(-)

diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index ad23b4cbe..695c58abe 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -39,8 +39,6 @@
 //====================
 #define ENABLE_2_5_0_ALPHA1 1
 
-// Enable removal of wipe tower magic object_id equal to 1000
-#define ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL (1 && ENABLE_2_5_0_ALPHA1)
 // Enable removal of legacy OpenGL calls
 #define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_5_0_ALPHA1)
 // Enable OpenGL ES
diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp
index 9945b4047..cedc7ef2a 100644
--- a/src/slic3r/GUI/3DScene.cpp
+++ b/src/slic3r/GUI/3DScene.cpp
@@ -912,7 +912,6 @@ void GLVolumeCollection::load_object_auxiliary(
 }
 
 #if ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 #if ENABLE_OPENGL_ES
 int GLVolumeCollection::load_wipe_tower_preview(
     float pos_x, float pos_y, float width, float depth, float height,
@@ -923,26 +922,9 @@ int GLVolumeCollection::load_wipe_tower_preview(
     float rotation_angle, bool size_unknown, float brim_width)
 #endif // ENABLE_OPENGL_ES
 #else
-#if ENABLE_OPENGL_ES
-int GLVolumeCollection::load_wipe_tower_preview(
-    int obj_idx, float pos_x, float pos_y, float width, float depth, float height,
-    float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh)
-#else
-int GLVolumeCollection::load_wipe_tower_preview(
-    int obj_idx, float pos_x, float pos_y, float width, float depth, float height,
-    float rotation_angle, bool size_unknown, float brim_width)
-#endif // ENABLE_OPENGL_ES
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-#else
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 int GLVolumeCollection::load_wipe_tower_preview(
     float pos_x, float pos_y, float width, float depth, float height,
     float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized)
-#else
-int GLVolumeCollection::load_wipe_tower_preview(
-    int obj_idx, float pos_x, float pos_y, float width, float depth, float height,
-    float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized)
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 #endif // ENABLE_LEGACY_OPENGL_REMOVAL
 {
     if (depth < 0.01f)
@@ -1210,11 +1192,7 @@ int GLVolumeCollection::load_wipe_tower_preview(
 #endif // !ENABLE_LEGACY_OPENGL_REMOVAL
     v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
     v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle));
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-    v.composite_id = GLVolume::CompositeID(INT_MAX, 0, 0);    
-#else
-    v.composite_id = GLVolume::CompositeID(obj_idx, 0, 0);
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
+    v.composite_id = GLVolume::CompositeID(INT_MAX, 0, 0);
     v.geometry_id.first = 0;
     v.geometry_id.second = wipe_tower_instance_id().id;
     v.is_wipe_tower = true;
diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp
index b48ad90a8..1e8897c4e 100644
--- a/src/slic3r/GUI/3DScene.hpp
+++ b/src/slic3r/GUI/3DScene.hpp
@@ -668,7 +668,6 @@ public:
         // Timestamp of the last change of the milestone
         size_t                          timestamp);
 
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 #if ENABLE_OPENGL_ES
     int load_wipe_tower_preview(
         float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr);
@@ -676,15 +675,6 @@ public:
     int load_wipe_tower_preview(
         float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width);
 #endif // ENABLE_OPENGL_ES
-#else
-#if ENABLE_OPENGL_ES
-    int load_wipe_tower_preview(
-        int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, TriangleMesh* out_mesh = nullptr);
-#else
-    int load_wipe_tower_preview(
-        int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width);
-#endif // ENABLE_OPENGL_ES
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 #else
     std::vector<int> load_object(
         const ModelObject 		*model_object,
@@ -710,13 +700,8 @@ public:
         size_t                          timestamp,
         bool 			   				opengl_initialized);
 
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
     int load_wipe_tower_preview(
         float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized);
-#else
-    int load_wipe_tower_preview(
-        int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized);
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 #endif // ENABLE_LEGACY_OPENGL_REMOVAL
 
 #if ENABLE_LEGACY_OPENGL_REMOVAL
diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp
index be232c178..562c67ceb 100644
--- a/src/slic3r/GUI/GCodeViewer.cpp
+++ b/src/slic3r/GUI/GCodeViewer.cpp
@@ -2349,21 +2349,11 @@ void GCodeViewer::load_shells(const Print& print, bool initialized)
             const float brim_width = print.wipe_tower_data(extruders_count).brim_width;
 
 #if ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
             m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
                 !print.is_step_done(psWipeTower), brim_width);
 #else
-            m_shells.volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
-                !print.is_step_done(psWipeTower), brim_width);
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-#else
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
             m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
                 !print.is_step_done(psWipeTower), brim_width, initialized);
-#else
-            m_shells.volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
-                !print.is_step_done(psWipeTower), brim_width, initialized);
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 #endif // ENABLE_LEGACY_OPENGL_REMOVAL
         }
     }
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 04a691871..f77eed369 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -1341,18 +1341,12 @@ ModelInstanceEPrintVolumeState GLCanvas3D::check_volumes_outside_state() const
 
 void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo, int instance_idx)
 {
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
     if (current_printer_technology() != ptSLA)
         return;
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 
     m_render_sla_auxiliaries = visible;
 
     for (GLVolume* vol : m_volumes.volumes) {
-#if !ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-        if (vol->composite_id.object_id == 1000)
-            continue; // the wipe tower
-#endif // !ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo)
         && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx)
         && vol->composite_id.volume_id < 0)
@@ -1363,14 +1357,8 @@ void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObje
 void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject* mo, int instance_idx, const ModelVolume* mv)
 {
     for (GLVolume* vol : m_volumes.volumes) {
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         if (vol->is_wipe_tower)
             vol->is_active = (visible && mo == nullptr);
-#else
-        if (vol->composite_id.object_id == 1000) { // wipe tower
-            vol->is_active = (visible && mo == nullptr);
-        }
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         else {
             if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo)
             && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx)
@@ -2348,7 +2336,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
             float brim_width = print->wipe_tower_data(extruders_count).brim_width;
 
 #if ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 #if ENABLE_OPENGL_ES
             int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
                 x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
@@ -2359,26 +2346,9 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
                 brim_width);
 #endif // ENABLE_OPENGL_ES
 #else
-#if ENABLE_OPENGL_ES
-            int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
-                1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
-                brim_width, &m_wipe_tower_mesh);
-#else
-            int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
-                1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
-                brim_width);
-#endif // ENABLE_OPENGL_ES
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-#else
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
             int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
                 x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
                 brim_width, m_initialized);
-#else
-            int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
-                1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
-                brim_width, m_initialized);
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 #endif // ENABLE_LEGACY_OPENGL_REMOVAL
             if (volume_idx_wipe_tower_old != -1)
                 map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new;
@@ -3855,15 +3825,9 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
                 model_object->invalidate_bounding_box();
             }
         }
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         else if (v->is_wipe_tower)
             // Move a wipe tower proxy.
             wipe_tower_origin = v->get_volume_offset();
-#else
-        else if (object_idx == 1000)
-            // Move a wipe tower proxy.
-            wipe_tower_origin = v->get_volume_offset();
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
     }
 
     // Fixes flying instances
@@ -3924,18 +3888,11 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
     Selection::EMode selection_mode = m_selection.get_mode();
 
     for (const GLVolume* v : m_volumes.volumes) {
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         if (v->is_wipe_tower) {
-#else
-        int object_idx = v->object_idx();
-        if (object_idx == 1000) { // the wipe tower
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
             const Vec3d offset = v->get_volume_offset();
             post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), v->get_volume_rotation().z())));
         }
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-        int object_idx = v->object_idx();
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
+        const int object_idx = v->object_idx();
         if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
             continue;
 
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index b8c04f8cf..0984ded3a 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -1960,15 +1960,9 @@ void ObjectList::del_layers_from_object(const int obj_idx)
 bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, const int type)
 {
     assert(idx >= 0);
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
     if (m_objects->empty() || int(m_objects->size()) <= obj_idx)
         // Cannot delete a wipe tower
         return false;
-#else
-    if (obj_idx == 1000 || idx<0)
-		// Cannot delete a wipe tower or volume with negative id
-		return false;
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 
     ModelObject* object = (*m_objects)[obj_idx];
 
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 91c901f78..eb8b5b01a 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -1253,11 +1253,7 @@ void Sidebar::show_info_sizer()
     ModelObjectPtrs objects = p->plater->model().objects;
     int obj_idx = selection.get_object_idx();
 
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
     if (m_mode < comExpert || objects.empty() || obj_idx < 0 || int(objects.size()) <= obj_idx ||
-#else
-    if (m_mode < comExpert || objects.empty() || obj_idx < 0 || obj_idx == 1000 ||
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         objects[obj_idx]->volumes.empty() ||                                            // hack to avoid crash when deleting the last object on the bed
         (selection.is_single_full_object() && objects[obj_idx]->instances.size()> 1) ||
         !(selection.is_single_full_instance() || selection.is_single_volume())) {
@@ -2932,23 +2928,15 @@ Selection& Plater::priv::get_selection()
 
 int Plater::priv::get_selected_object_idx() const
 {
-    int idx = get_selection().get_object_idx();
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
+    const int idx = get_selection().get_object_idx();
     return (0 <= idx && idx < int(model.objects.size())) ? idx : -1;
-#else
-    return ((0 <= idx) && (idx < 1000)) ? idx : -1;
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 }
 
 int Plater::priv::get_selected_volume_idx() const
 {
     auto& selection = get_selection();
-    int idx = selection.get_object_idx();
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
+    const int idx = selection.get_object_idx();
     if (idx < 0 || int(model.objects.size()) <= idx)
-#else
-    if ((0 > idx) || (idx > 1000))
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         return-1;
     const GLVolume* v = selection.get_first_volume();
     if (model.objects[idx]->volumes.size() > 1)
diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp
index c6ddd1fa3..2423b10a0 100644
--- a/src/slic3r/GUI/Selection.cpp
+++ b/src/slic3r/GUI/Selection.cpp
@@ -544,11 +544,7 @@ bool Selection::is_single_full_instance() const
 bool Selection::is_from_single_object() const
 {
     const int idx = get_object_idx();
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
     return 0 <= idx && idx < int(m_model->objects.size());
-#else
-    return 0 <= idx && idx < 1000;
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 }
 
 bool Selection::is_sla_compliant() const
@@ -1404,16 +1400,10 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
         if (done.size() == m_volumes->size())
             break;
 
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         if ((*m_volumes)[i]->is_wipe_tower)
             continue;
 
         int object_idx = (*m_volumes)[i]->object_idx();
-#else
-        int object_idx = (*m_volumes)[i]->object_idx();
-        if (object_idx >= 1000)
-            continue;
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
 
         // Process unselected volumes of the object.
         for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
@@ -1458,16 +1448,10 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
         if (done.size() == m_volumes->size())
             break;
 
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         if ((*m_volumes)[i]->is_wipe_tower)
             continue;
 
-        int object_idx = (*m_volumes)[i]->object_idx();
-#else
-        int object_idx = (*m_volumes)[i]->object_idx();
-        if (object_idx >= 1000)
-            continue;
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
+        const int object_idx = (*m_volumes)[i]->object_idx();
 
         // Process unselected volumes of the object.
         for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) {
@@ -2965,17 +2949,10 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_
             break;
 
         const GLVolume* volume_i = (*m_volumes)[i];
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         if (volume_i->is_wipe_tower)
             continue;
 
         const int object_idx = volume_i->object_idx();
-#else
-        const int object_idx = volume_i->object_idx();
-        if (object_idx >= 1000)
-            continue;
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-
         const int instance_idx = volume_i->instance_idx();
 #if ENABLE_WORLD_COORDINATE
         const Geometry::Transformation& curr_inst_trafo_i = volume_i->get_instance_transformation();
@@ -3073,17 +3050,10 @@ void Selection::synchronize_unselected_volumes()
 {
     for (unsigned int i : m_list) {
         const GLVolume* volume = (*m_volumes)[i];
-#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
         if (volume->is_wipe_tower)
             continue;
 
         const int object_idx = volume->object_idx();
-#else
-        const int object_idx = volume->object_idx();
-        if (object_idx >= 1000)
-            continue;
-#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-
         const int volume_idx = volume->volume_idx();
 #if ENABLE_WORLD_COORDINATE
         const Geometry::Transformation& trafo = volume->get_volume_transformation();

From 24f671e924cbf673762e0c7e302c28f81d124edf Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Wed, 19 Oct 2022 12:32:54 +0200
Subject: [PATCH 2/5] Little clean-up of ConstVectorOfPtrsAdaptor to be more
 vector like.

---
 src/libslic3r/GCode/ToolOrdering.cpp | 2 +-
 src/libslic3r/Print.hpp              | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp
index 870096bb9..c5554c2fa 100644
--- a/src/libslic3r/GCode/ToolOrdering.cpp
+++ b/src/libslic3r/GCode/ToolOrdering.cpp
@@ -658,7 +658,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
         return std::max(0.f, volume_to_wipe); // Soluble filament cannot be wiped in a random infill, neither the filament after it
 
     // we will sort objects so that dedicated for wiping are at the beginning:
-    ConstPrintObjectPtrs object_list = print.objects().vector();
+    ConstPrintObjectPtrs object_list(print.objects().begin(), print.objects().end());
     std::sort(object_list.begin(), object_list.end(), [](const PrintObject* a, const PrintObject* b) { return a->config().wipe_into_objects; });
 
     // We will now iterate through
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index c2777083d..967c9e707 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -129,7 +129,6 @@ public:
     bool                    empty() const { return m_data->empty(); }
     const T*                operator[](size_t i) const { return (*m_data)[i]; }
     const T*                at(size_t i) const { return m_data->at(i); }
-    std::vector<const T*>   vector() const { return std::vector<const T*>(this->begin(), this->end()); }
 protected:
     ConstVectorOfPtrsAdaptor(const std::vector<T*> *data) : m_data(data) {}
 private:

From acbc60f3e357825f74108942386343698a4c6ed0 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Wed, 19 Oct 2022 15:50:17 +0200
Subject: [PATCH 3/5] Better const correctness

---
 src/libslic3r/Brim.cpp          | 2 +-
 src/libslic3r/TreeSupport.cpp   | 2 +-
 src/slic3r/GUI/DoubleSlider.cpp | 6 +++---
 src/slic3r/GUI/DoubleSlider.hpp | 4 ++--
 src/slic3r/GUI/GUI_Preview.cpp  | 2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp
index 9ed56bea4..5239d7f03 100644
--- a/src/libslic3r/Brim.cpp
+++ b/src/libslic3r/Brim.cpp
@@ -564,7 +564,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
     }
 #endif // BRIM_DEBUG_TO_SVG
 
-    const bool could_brim_intersects_skirt = std::any_of(print.objects().begin(), print.objects().end(), [&print](PrintObject *object) {
+    const bool could_brim_intersects_skirt = std::any_of(print.objects().begin(), print.objects().end(), [&print](const PrintObject *object) {
         const BrimType &bt = object->config().brim_type;
         return (bt == btOuterOnly || bt == btOuterAndInner) && print.config().skirt_distance.value < object->config().brim_width;
     });
diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp
index d5758cf07..b60744e32 100644
--- a/src/libslic3r/TreeSupport.cpp
+++ b/src/libslic3r/TreeSupport.cpp
@@ -3908,7 +3908,7 @@ static void generate_support_areas(Print &print, const BuildVolume &build_volume
 void fff_tree_support_generate(PrintObject &print_object, std::function<void()> throw_on_cancel)
 {
     size_t idx = 0;
-    for (PrintObject* po : print_object.print()->objects()) {
+    for (const PrintObject *po : print_object.print()->objects()) {
         if (po == &print_object)
             break;
         ++idx;
diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp
index 717af39ba..31b2c5c90 100644
--- a/src/slic3r/GUI/DoubleSlider.cpp
+++ b/src/slic3r/GUI/DoubleSlider.cpp
@@ -2123,13 +2123,13 @@ void Control::show_cog_icon_context_menu()
     GUI::wxGetApp().plater()->PopupMenu(&menu);
 }
 
-bool check_color_change(PrintObject* object, size_t frst_layer_id, size_t layers_cnt, bool check_overhangs, std::function<bool(Layer*)> break_condition)
+bool check_color_change(const PrintObject* object, size_t frst_layer_id, size_t layers_cnt, bool check_overhangs, std::function<bool(const Layer*)> break_condition)
 {
     double prev_area = area(object->get_layer(frst_layer_id)->lslices);
 
     bool detected = false;
     for (size_t i = frst_layer_id+1; i < layers_cnt; i++) {
-        Layer* layer = object->get_layer(i);
+        const Layer* layer = object->get_layer(i);
         double cur_area = area(layer->lslices);
 
         // check for overhangs
@@ -2169,7 +2169,7 @@ void Control::auto_color_change()
         if (object->layer_count() < 2)
             continue;
 
-        check_color_change(object, 1, object->layers().size(), false, [this, extruders_cnt](Layer* layer)
+        check_color_change(object, 1, object->layers().size(), false, [this, extruders_cnt](const Layer* layer)
         {
             int tick = get_tick_from_value(layer->print_z);
             if (tick >= 0 && !m_ticks.has_tick(tick)) {
diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp
index e4654d604..3a862c286 100644
--- a/src/slic3r/GUI/DoubleSlider.hpp
+++ b/src/slic3r/GUI/DoubleSlider.hpp
@@ -31,10 +31,10 @@ constexpr double epsilon() { return 0.0011; }
 bool equivalent_areas(const double& bottom_area, const double& top_area);
 
 // return true if color change was detected
-bool check_color_change(PrintObject* object, size_t frst_layer_id, size_t layers_cnt, bool check_overhangs,
+bool check_color_change(const PrintObject* object, size_t frst_layer_id, size_t layers_cnt, bool check_overhangs,
                         // what to do with detected color change
                         // and return true when detection have to be desturbed
-                        std::function<bool(Layer*)> break_condition);
+                        std::function<bool(const Layer*)> break_condition);
 
 // custom message the slider sends to its parent to notify a tick-change:
 wxDECLARE_EVENT(wxCUSTOMEVT_TICKSCHANGED, wxEvent);
diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp
index 7989c3cdc..93cbca3c4 100644
--- a/src/slic3r/GUI/GUI_Preview.cpp
+++ b/src/slic3r/GUI/GUI_Preview.cpp
@@ -574,7 +574,7 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
             if (i < min_solid_height)
                 continue;
 
-            if (DoubleSlider::check_color_change(object, i, num_layers, true, [this, object](Layer*) {
+            if (DoubleSlider::check_color_change(object, i, num_layers, true, [this, object](const Layer*) {
                 NotificationManager* notif_mngr = wxGetApp().plater()->get_notification_manager();
                 notif_mngr->push_notification(
                     NotificationType::SignDetected, NotificationManager::NotificationLevel::PrintInfoNotificationLevel,

From 2ced7629482ea0b0feab66906b6a97fe0d57b747 Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Wed, 19 Oct 2022 16:26:59 +0200
Subject: [PATCH 4/5] Integrating a C++20 like span library
 https://github.com/tcbrindle/span

Replacing a homebrew const pointer wrapper const correctness helper
with the C++20 like span library.

One day when we switch to C++20 we will just use the C++20 spans instead.
---
 src/CMakeLists.txt                          |   1 +
 src/libslic3r/Brim.cpp                      |   2 +-
 src/libslic3r/GCode.hpp                     |   1 -
 src/libslic3r/MultiMaterialSegmentation.cpp |   4 +-
 src/libslic3r/Print.hpp                     |  59 +-
 src/libslic3r/PrintObject.cpp               |   2 +-
 src/tcbspan/CMakeLists.txt                  |   6 +
 src/tcbspan/README.md                       | 124 ++++
 src/tcbspan/span.hpp                        | 618 ++++++++++++++++++++
 tests/fff_print/test_print.cpp              |   2 +-
 tests/fff_print/test_printobject.cpp        |   6 +-
 tests/fff_print/test_support_material.cpp   |   2 +-
 12 files changed, 770 insertions(+), 57 deletions(-)
 create mode 100644 src/tcbspan/CMakeLists.txt
 create mode 100644 src/tcbspan/README.md
 create mode 100644 src/tcbspan/span.hpp

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 50eccfc84..1c1b16638 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,6 +14,7 @@ add_subdirectory(libigl)
 add_subdirectory(hints)
 add_subdirectory(qoi)
 add_subdirectory(libnest2d)
+add_subdirectory(tcbspan)
 
 find_package(Qhull 7.2 REQUIRED)
 add_library(qhull INTERFACE)
diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp
index 5239d7f03..62d886785 100644
--- a/src/libslic3r/Brim.cpp
+++ b/src/libslic3r/Brim.cpp
@@ -39,7 +39,7 @@ static void append_and_translate(Polygons &dst, const Polygons &src, const Print
         dst[dst_idx].translate(instance.shift.x(), instance.shift.y());
 }
 
-static float max_brim_width(const ConstPrintObjectPtrsAdaptor &objects)
+static float max_brim_width(const SpanOfConstPtrs<PrintObject> &objects)
 {
     assert(!objects.empty());
     return float(std::accumulate(objects.begin(), objects.end(), 0.,
diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp
index ce4a505fc..4592402e3 100644
--- a/src/libslic3r/GCode.hpp
+++ b/src/libslic3r/GCode.hpp
@@ -32,7 +32,6 @@ class GCode;
 
 namespace { struct Item; }
 struct PrintInstance;
-class ConstPrintObjectPtrsAdaptor;
 
 class OozePrevention {
 public:
diff --git a/src/libslic3r/MultiMaterialSegmentation.cpp b/src/libslic3r/MultiMaterialSegmentation.cpp
index 9560096be..21b53c40d 100644
--- a/src/libslic3r/MultiMaterialSegmentation.cpp
+++ b/src/libslic3r/MultiMaterialSegmentation.cpp
@@ -1305,7 +1305,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
 {
     const size_t num_extruders = print_object.print()->config().nozzle_diameter.size() + 1;
     const size_t num_layers    = input_expolygons.size();
-    const ConstLayerPtrsAdaptor layers = print_object.layers();
+    const SpanOfConstPtrs<Layer> layers = print_object.layers();
 
     // Maximum number of top / bottom layers accounts for maximum overlap of one thread group into a neighbor thread group.
     int max_top_layers = 0;
@@ -1685,7 +1685,7 @@ std::vector<std::vector<ExPolygons>> multi_material_segmentation_by_painting(con
     std::vector<std::vector<PaintedLine>> painted_lines(num_layers);
     std::array<std::mutex, 64>            painted_lines_mutex;
     std::vector<EdgeGrid::Grid>           edge_grids(num_layers);
-    const ConstLayerPtrsAdaptor           layers = print_object.layers();
+    const SpanOfConstPtrs<Layer>          layers = print_object.layers();
     std::vector<ExPolygons>               input_expolygons(num_layers);
 
     throw_on_cancel_callback();
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index 967c9e707..9e21111ce 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -21,6 +21,7 @@
 
 #include <functional>
 #include <set>
+#include <tcbspan/span.hpp>
 
 namespace Slic3r {
 
@@ -117,37 +118,12 @@ private:
 inline bool operator==(const PrintRegion &lhs, const PrintRegion &rhs) { return lhs.config_hash() == rhs.config_hash() && lhs.config() == rhs.config(); }
 inline bool operator!=(const PrintRegion &lhs, const PrintRegion &rhs) { return ! (lhs == rhs); }
 
-template<typename T>
-class ConstVectorOfPtrsAdaptor {
-public:
-    // Returning a non-const pointer to const pointers to T.
-    T * const *             begin() const { return m_data->data(); }
-    T * const *             end()   const { return m_data->data() + m_data->size(); }
-    const T*                front() const { return m_data->front(); }
-    const T*                back()  const { return m_data->back(); }
-    size_t                  size()  const { return m_data->size(); }
-    bool                    empty() const { return m_data->empty(); }
-    const T*                operator[](size_t i) const { return (*m_data)[i]; }
-    const T*                at(size_t i) const { return m_data->at(i); }
-protected:
-    ConstVectorOfPtrsAdaptor(const std::vector<T*> *data) : m_data(data) {}
-private:
-    const std::vector<T*> *m_data;
-};
+// For const correctness: Wrapping a vector of non-const pointers as a span of const pointers.
+template<class T>
+using SpanOfConstPtrs           = tcb::span<const T* const>;
 
-typedef std::vector<Layer*>       LayerPtrs;
-typedef std::vector<const Layer*> ConstLayerPtrs;
-class ConstLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor<Layer> {
-    friend PrintObject;
-    ConstLayerPtrsAdaptor(const LayerPtrs *data) : ConstVectorOfPtrsAdaptor<Layer>(data) {}
-};
-
-typedef std::vector<SupportLayer*>        SupportLayerPtrs;
-typedef std::vector<const SupportLayer*>  ConstSupportLayerPtrs;
-class ConstSupportLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor<SupportLayer> {
-    friend PrintObject;
-    ConstSupportLayerPtrsAdaptor(const SupportLayerPtrs *data) : ConstVectorOfPtrsAdaptor<SupportLayer>(data) {}
-};
+using LayerPtrs                 = std::vector<Layer*>;
+using SupportLayerPtrs          = std::vector<SupportLayer*>;
 
 class BoundingBoxf3;        // TODO: for temporary constructor parameter
 
@@ -255,8 +231,8 @@ public:
     // Size of an object: XYZ in scaled coordinates. The size might not be quite snug in XY plane.
     const Vec3crd&               size() const			{ return m_size; }
     const PrintObjectConfig&     config() const         { return m_config; }    
-    ConstLayerPtrsAdaptor        layers() const         { return ConstLayerPtrsAdaptor(&m_layers); }
-    ConstSupportLayerPtrsAdaptor support_layers() const { return ConstSupportLayerPtrsAdaptor(&m_support_layers); }
+    auto                         layers() const         { return SpanOfConstPtrs<Layer>(const_cast<const Layer* const* const>(m_layers.data()), m_layers.size()); }
+    auto                         support_layers() const { return SpanOfConstPtrs<SupportLayer>(const_cast<const SupportLayer* const* const>(m_support_layers.data()), m_support_layers.size()); }
     const Transform3d&           trafo() const          { return m_trafo; }
     // Trafo with the center_offset() applied after the transformation, to center the object in XY before slicing.
     Transform3d                  trafo_centered() const 
@@ -497,21 +473,10 @@ struct PrintStatistics
     }
 };
 
-typedef std::vector<PrintObject*>       PrintObjectPtrs;
-typedef std::vector<const PrintObject*> ConstPrintObjectPtrs;
-class ConstPrintObjectPtrsAdaptor : public ConstVectorOfPtrsAdaptor<PrintObject> {
-    friend Print;
-    ConstPrintObjectPtrsAdaptor(const PrintObjectPtrs *data) : ConstVectorOfPtrsAdaptor<PrintObject>(data) {}
-};
+using PrintObjectPtrs          = std::vector<PrintObject*>;
+using ConstPrintObjectPtrs     = std::vector<const PrintObject*>;
 
-typedef std::vector<PrintRegion*>       PrintRegionPtrs;
-/*
-typedef std::vector<const PrintRegion*> ConstPrintRegionPtrs;
-class ConstPrintRegionPtrsAdaptor : public ConstVectorOfPtrsAdaptor<PrintRegion> {
-    friend Print;
-    ConstPrintRegionPtrsAdaptor(const PrintRegionPtrs *data) : ConstVectorOfPtrsAdaptor<PrintRegion>(data) {}
-};
-*/
+using PrintRegionPtrs          = std::vector<PrintRegion*>;
 
 // The complete print tray with possibly multiple objects.
 class Print : public PrintBaseWithState<PrintStep, psCount>
@@ -574,7 +539,7 @@ public:
     const PrintConfig&          config() const { return m_config; }
     const PrintObjectConfig&    default_object_config() const { return m_default_object_config; }
     const PrintRegionConfig&    default_region_config() const { return m_default_region_config; }
-    ConstPrintObjectPtrsAdaptor objects() const { return ConstPrintObjectPtrsAdaptor(&m_objects); }
+    SpanOfConstPtrs<PrintObject> objects() const { return SpanOfConstPtrs<PrintObject>(const_cast<const PrintObject* const* const>(m_objects.data()), m_objects.size()); }
     PrintObject*                get_object(size_t idx) { return const_cast<PrintObject*>(m_objects[idx]); }
     const PrintObject*          get_object(size_t idx) const { return m_objects[idx]; }
     // PrintObject by its ObjectID, to be used to uniquely bind slicing warnings to their source PrintObjects
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index 9ffb57a72..bdcb034ab 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -2205,7 +2205,7 @@ void PrintObject::_generate_support_material()
     }
 }
 
-static void project_triangles_to_slabs(ConstLayerPtrsAdaptor layers, const indexed_triangle_set &custom_facets, const Transform3f &tr, bool seam, std::vector<Polygons> &out)
+static void project_triangles_to_slabs(SpanOfConstPtrs<Layer> layers, const indexed_triangle_set &custom_facets, const Transform3f &tr, bool seam, std::vector<Polygons> &out)
 {
     if (custom_facets.indices.empty())
         return;
diff --git a/src/tcbspan/CMakeLists.txt b/src/tcbspan/CMakeLists.txt
new file mode 100644
index 000000000..0668f838e
--- /dev/null
+++ b/src/tcbspan/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(tcbspan)
+
+add_library(tcbspan STATIC
+    span.hpp
+)
diff --git a/src/tcbspan/README.md b/src/tcbspan/README.md
new file mode 100644
index 000000000..6e2fba84c
--- /dev/null
+++ b/src/tcbspan/README.md
@@ -0,0 +1,124 @@
+Bundled with PrusaSlicer: 
+https://github.com/tcbrindle/span
+commit 836dc6a0efd9849cb194e88e4aa2387436bb079b
+This is not the full distribution, it only contains README and span.hpp
+Original README follows:
+
+
+[![Standard](https://img.shields.io/badge/c%2B%2B-11/14/17/20-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
+[![License](https://img.shields.io/badge/license-BSL-blue.svg)](http://www.boost.org/LICENSE_1_0.txt)
+[![Build Status](https://travis-ci.org/tcbrindle/span.svg?branch=master)](https://travis-ci.org/tcbrindle/span)
+[![Build status](https://ci.appveyor.com/api/projects/status/ow7cj56s108fs439/branch/master?svg=true)](https://ci.appveyor.com/project/tcbrindle/span/branch/master)
+[![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/-vlZZR) 
+
+`std::span` implementation for C++11 and later
+==============================================
+
+This repository contains a single-header implementation of C++20's `std::span`,
+conforming to the C++20 committee draft.
+It is compatible with C++11, but will use newer language features if they
+are available.
+
+It differs from the implementation in the [Microsoft GSL](https://github.com/Microsoft/GSL/)
+in that it is single-header and does not depend on any other GSL facilities. It
+also works with C++11, while the GSL version requires C++14.
+
+Usage
+-----
+
+The recommended way to use the implementation simply copy the file `span.hpp`
+from `include/tcb/` into your own sources and `#include` it like
+any other header. By default, it lives in namespace `tcb`, but this can be
+customised by setting the macro `TCB_SPAN_NAMESPACE_NAME` to an appropriate string
+before `#include`-ing the header -- or simply edit the source code.
+
+The rest of the repository contains testing machinery, and is not required for
+use.
+
+Compatibility
+-------------
+
+This implementation requires a conforming C++11 (or later) compiler,  and is tested as far
+back as GCC 5, Clang 3.5 and MSVC 2015 Update 3. Older compilers may work, but this is not guaranteed.
+
+Documentation
+-------------
+
+Documentation for `std::span` is available [on cppreference](https://en.cppreference.com/w/cpp/container/span).
+
+Implementation Notes
+--------------------
+
+### Bounds Checking ###
+
+This implementation of `span` includes optional bounds checking, which is handled
+either by throwing an exception or by calling `std::terminate()`.
+
+The default behaviour with C++14 and later is to check the macro `NDEBUG`:
+if this is set, bounds checking is disabled. Otherwise, `std::terminate()` will
+be called if there is a precondition violation (i.e. the same behaviour as
+`assert()`). If you wish to terminate on errors even if `NDEBUG` is set, define
+the symbol `TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION` before `#include`-ing the
+header.
+
+Alternatively, if you want to throw on a contract violation, define
+`TCB_SPAN_THROW_ON_CONTRACT_VIOLATION`. This will throw an exception of an
+implementation-defined type (deriving from `std::logic_error`), allowing
+cleanup to happen. Note that defining this symbol will cause the checks to be
+run even if `NDEBUG` is set.
+
+Lastly, if you wish to disable contract checking even in debug builds,
+`#define TCB_SPAN_NO_CONTRACT_CHECKING`.
+
+Under C++11, due to the restrictions on `constexpr` functions, contract checking
+is disabled by default even if `NDEBUG` is not set. You can change this by
+defining either of the above symbols, but this will result in most of `span`'s
+interface becoming non-`constexpr`.
+
+### `constexpr` ###
+
+This implementation is fully `constexpr` under C++17 and later. Under earlier
+versions, it is "as `constexpr` as possible".
+
+Note that even in C++17, it is generally not possible to declare a `span`
+as non-default constructed `constexpr` variable, for the same reason that you
+cannot form a `constexpr` pointer to a value: it involves taking the address of
+a compile-time variable in a way that would be visible at run-time.
+You can however use a `span` freely in a `constexpr` function. For example:
+
+```cpp
+// Okay, even in C++11
+constexpr std::ptrdiff_t get_span_size(span<const int> span)
+{
+    return span.size();
+}
+
+constexpr int arr[] = {1, 2, 3};
+constexpr auto size = get_span_size(arr); // Okay
+constexpr span<const int> span{arr}; // ERROR -- not a constant expression
+constexpr const int* p = arr; // ERROR -- same
+```
+
+Constructor deduction guides are provided if the compiler supports them. For
+older compilers, a set of `make_span()` functions are provided as an extension
+which use the same logic, for example:
+
+   ```cpp
+   constexpr int c_array[] = {1, 2, 3};
+   std::array<int, 3> std_array{1, 2, 3};
+   const std::vector<int> vec{1, 2, 3};
+
+   auto s1 = make_span(c_array);   // returns span<const int, 3>
+   auto s2 = make_span(std_array); // returns span<int, 3>
+   auto s3 = make_span(vec);       // returns span<const int, dynamic_extent>
+   ```
+
+Alternatives
+------------
+
+* [Microsoft/GSL](https://github.com/Microsoft/GSL): The original `span` reference
+  implementation from which `std::span` was born.
+  
+* [martinmoene/span_lite](https://github.com/martinmoene/span-lite): An
+  alternative implementation which offers C++98 compatibility.
+
diff --git a/src/tcbspan/span.hpp b/src/tcbspan/span.hpp
new file mode 100644
index 000000000..fdc3a988a
--- /dev/null
+++ b/src/tcbspan/span.hpp
@@ -0,0 +1,618 @@
+
+/*
+This is an implementation of C++20's std::span
+http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf
+*/
+
+//          Copyright Tristan Brindle 2018.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file ../../LICENSE_1_0.txt or copy at
+//          https://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef TCB_SPAN_HPP_INCLUDED
+#define TCB_SPAN_HPP_INCLUDED
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <type_traits>
+
+#ifndef TCB_SPAN_NO_EXCEPTIONS
+// Attempt to discover whether we're being compiled with exception support
+#if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND))
+#define TCB_SPAN_NO_EXCEPTIONS
+#endif
+#endif
+
+#ifndef TCB_SPAN_NO_EXCEPTIONS
+#include <cstdio>
+#include <stdexcept>
+#endif
+
+// Various feature test macros
+
+#ifndef TCB_SPAN_NAMESPACE_NAME
+#define TCB_SPAN_NAMESPACE_NAME tcb
+#endif
+
+#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
+#define TCB_SPAN_HAVE_CPP17
+#endif
+
+#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
+#define TCB_SPAN_HAVE_CPP14
+#endif
+
+namespace TCB_SPAN_NAMESPACE_NAME {
+
+// Establish default contract checking behavior
+#if !defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION) &&                          \
+    !defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) &&                      \
+    !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
+#if defined(NDEBUG) || !defined(TCB_SPAN_HAVE_CPP14)
+#define TCB_SPAN_NO_CONTRACT_CHECKING
+#else
+#define TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION
+#endif
+#endif
+
+#if defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION)
+struct contract_violation_error : std::logic_error {
+    explicit contract_violation_error(const char* msg) : std::logic_error(msg)
+    {}
+};
+
+inline void contract_violation(const char* msg)
+{
+    throw contract_violation_error(msg);
+}
+
+#elif defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION)
+[[noreturn]] inline void contract_violation(const char* /*unused*/)
+{
+    std::terminate();
+}
+#endif
+
+#if !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
+#define TCB_SPAN_STRINGIFY(cond) #cond
+#define TCB_SPAN_EXPECT(cond)                                                  \
+    cond ? (void) 0 : contract_violation("Expected " TCB_SPAN_STRINGIFY(cond))
+#else
+#define TCB_SPAN_EXPECT(cond)
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_inline_variables)
+#define TCB_SPAN_INLINE_VAR inline
+#else
+#define TCB_SPAN_INLINE_VAR
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP14) ||                                            \
+    (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
+#define TCB_SPAN_HAVE_CPP14_CONSTEXPR
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR)
+#define TCB_SPAN_CONSTEXPR14 constexpr
+#else
+#define TCB_SPAN_CONSTEXPR14
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR) &&                                  \
+    (!defined(_MSC_VER) || _MSC_VER > 1900)
+#define TCB_SPAN_CONSTEXPR_ASSIGN constexpr
+#else
+#define TCB_SPAN_CONSTEXPR_ASSIGN
+#endif
+
+#if defined(TCB_SPAN_NO_CONTRACT_CHECKING)
+#define TCB_SPAN_CONSTEXPR11 constexpr
+#else
+#define TCB_SPAN_CONSTEXPR11 TCB_SPAN_CONSTEXPR14
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_deduction_guides)
+#define TCB_SPAN_HAVE_DEDUCTION_GUIDES
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_byte)
+#define TCB_SPAN_HAVE_STD_BYTE
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_array_constexpr)
+#define TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC
+#endif
+
+#if defined(TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC)
+#define TCB_SPAN_ARRAY_CONSTEXPR constexpr
+#else
+#define TCB_SPAN_ARRAY_CONSTEXPR
+#endif
+
+#ifdef TCB_SPAN_HAVE_STD_BYTE
+using byte = std::byte;
+#else
+using byte = unsigned char;
+#endif
+
+#if defined(TCB_SPAN_HAVE_CPP17)
+#define TCB_SPAN_NODISCARD [[nodiscard]]
+#else
+#define TCB_SPAN_NODISCARD
+#endif
+
+TCB_SPAN_INLINE_VAR constexpr std::size_t dynamic_extent = SIZE_MAX;
+
+template <typename ElementType, std::size_t Extent = dynamic_extent>
+class span;
+
+namespace detail {
+
+template <typename E, std::size_t S>
+struct span_storage {
+    constexpr span_storage() noexcept = default;
+
+    constexpr span_storage(E* p_ptr, std::size_t /*unused*/) noexcept
+       : ptr(p_ptr)
+    {}
+
+    E* ptr = nullptr;
+    static constexpr std::size_t size = S;
+};
+
+template <typename E>
+struct span_storage<E, dynamic_extent> {
+    constexpr span_storage() noexcept = default;
+
+    constexpr span_storage(E* p_ptr, std::size_t p_size) noexcept
+        : ptr(p_ptr), size(p_size)
+    {}
+
+    E* ptr = nullptr;
+    std::size_t size = 0;
+};
+
+// Reimplementation of C++17 std::size() and std::data()
+#if defined(TCB_SPAN_HAVE_CPP17) ||                                            \
+    defined(__cpp_lib_nonmember_container_access)
+using std::data;
+using std::size;
+#else
+template <class C>
+constexpr auto size(const C& c) -> decltype(c.size())
+{
+    return c.size();
+}
+
+template <class T, std::size_t N>
+constexpr std::size_t size(const T (&)[N]) noexcept
+{
+    return N;
+}
+
+template <class C>
+constexpr auto data(C& c) -> decltype(c.data())
+{
+    return c.data();
+}
+
+template <class C>
+constexpr auto data(const C& c) -> decltype(c.data())
+{
+    return c.data();
+}
+
+template <class T, std::size_t N>
+constexpr T* data(T (&array)[N]) noexcept
+{
+    return array;
+}
+
+template <class E>
+constexpr const E* data(std::initializer_list<E> il) noexcept
+{
+    return il.begin();
+}
+#endif // TCB_SPAN_HAVE_CPP17
+
+#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_void_t)
+using std::void_t;
+#else
+template <typename...>
+using void_t = void;
+#endif
+
+template <typename T>
+using uncvref_t =
+    typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+
+template <typename>
+struct is_span : std::false_type {};
+
+template <typename T, std::size_t S>
+struct is_span<span<T, S>> : std::true_type {};
+
+template <typename>
+struct is_std_array : std::false_type {};
+
+template <typename T, std::size_t N>
+struct is_std_array<std::array<T, N>> : std::true_type {};
+
+template <typename, typename = void>
+struct has_size_and_data : std::false_type {};
+
+template <typename T>
+struct has_size_and_data<T, void_t<decltype(detail::size(std::declval<T>())),
+                                   decltype(detail::data(std::declval<T>()))>>
+    : std::true_type {};
+
+template <typename C, typename U = uncvref_t<C>>
+struct is_container {
+    static constexpr bool value =
+        !is_span<U>::value && !is_std_array<U>::value &&
+        !std::is_array<U>::value && has_size_and_data<C>::value;
+};
+
+template <typename T>
+using remove_pointer_t = typename std::remove_pointer<T>::type;
+
+template <typename, typename, typename = void>
+struct is_container_element_type_compatible : std::false_type {};
+
+template <typename T, typename E>
+struct is_container_element_type_compatible<
+    T, E,
+    typename std::enable_if<
+        !std::is_same<
+            typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type,
+            void>::value &&
+        std::is_convertible<
+            remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[],
+            E (*)[]>::value
+        >::type>
+    : std::true_type {};
+
+template <typename, typename = size_t>
+struct is_complete : std::false_type {};
+
+template <typename T>
+struct is_complete<T, decltype(sizeof(T))> : std::true_type {};
+
+} // namespace detail
+
+template <typename ElementType, std::size_t Extent>
+class span {
+    static_assert(std::is_object<ElementType>::value,
+                  "A span's ElementType must be an object type (not a "
+                  "reference type or void)");
+    static_assert(detail::is_complete<ElementType>::value,
+                  "A span's ElementType must be a complete type (not a forward "
+                  "declaration)");
+    static_assert(!std::is_abstract<ElementType>::value,
+                  "A span's ElementType cannot be an abstract class type");
+
+    using storage_type = detail::span_storage<ElementType, Extent>;
+
+public:
+    // constants and types
+    using element_type = ElementType;
+    using value_type = typename std::remove_cv<ElementType>::type;
+    using size_type = std::size_t;
+    using difference_type = std::ptrdiff_t;
+    using pointer = element_type*;
+    using const_pointer = const element_type*;
+    using reference = element_type&;
+    using const_reference = const element_type&;
+    using iterator = pointer;
+    using reverse_iterator = std::reverse_iterator<iterator>;
+
+    static constexpr size_type extent = Extent;
+
+    // [span.cons], span constructors, copy, assignment, and destructor
+    template <
+        std::size_t E = Extent,
+        typename std::enable_if<(E == dynamic_extent || E <= 0), int>::type = 0>
+    constexpr span() noexcept
+    {}
+
+    TCB_SPAN_CONSTEXPR11 span(pointer ptr, size_type count)
+        : storage_(ptr, count)
+    {
+        TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent);
+    }
+
+    TCB_SPAN_CONSTEXPR11 span(pointer first_elem, pointer last_elem)
+        : storage_(first_elem, last_elem - first_elem)
+    {
+        TCB_SPAN_EXPECT(extent == dynamic_extent ||
+                        last_elem - first_elem ==
+                            static_cast<std::ptrdiff_t>(extent));
+    }
+
+    template <std::size_t N, std::size_t E = Extent,
+              typename std::enable_if<
+                  (E == dynamic_extent || N == E) &&
+                      detail::is_container_element_type_compatible<
+                          element_type (&)[N], ElementType>::value,
+                  int>::type = 0>
+    constexpr span(element_type (&arr)[N]) noexcept : storage_(arr, N)
+    {}
+
+    template <typename T, std::size_t N, std::size_t E = Extent,
+              typename std::enable_if<
+                  (E == dynamic_extent || N == E) &&
+                      detail::is_container_element_type_compatible<
+                          std::array<T, N>&, ElementType>::value,
+                  int>::type = 0>
+    TCB_SPAN_ARRAY_CONSTEXPR span(std::array<T, N>& arr) noexcept
+        : storage_(arr.data(), N)
+    {}
+
+    template <typename T, std::size_t N, std::size_t E = Extent,
+              typename std::enable_if<
+                  (E == dynamic_extent || N == E) &&
+                      detail::is_container_element_type_compatible<
+                          const std::array<T, N>&, ElementType>::value,
+                  int>::type = 0>
+    TCB_SPAN_ARRAY_CONSTEXPR span(const std::array<T, N>& arr) noexcept
+        : storage_(arr.data(), N)
+    {}
+
+    template <
+        typename Container, std::size_t E = Extent,
+        typename std::enable_if<
+            E == dynamic_extent && detail::is_container<Container>::value &&
+                detail::is_container_element_type_compatible<
+                    Container&, ElementType>::value,
+            int>::type = 0>
+    constexpr span(Container& cont)
+        : storage_(detail::data(cont), detail::size(cont))
+    {}
+
+    template <
+        typename Container, std::size_t E = Extent,
+        typename std::enable_if<
+            E == dynamic_extent && detail::is_container<Container>::value &&
+                detail::is_container_element_type_compatible<
+                    const Container&, ElementType>::value,
+            int>::type = 0>
+    constexpr span(const Container& cont)
+        : storage_(detail::data(cont), detail::size(cont))
+    {}
+
+    constexpr span(const span& other) noexcept = default;
+
+    template <typename OtherElementType, std::size_t OtherExtent,
+              typename std::enable_if<
+                  (Extent == dynamic_extent || OtherExtent == dynamic_extent ||
+                   Extent == OtherExtent) &&
+                      std::is_convertible<OtherElementType (*)[],
+                                          ElementType (*)[]>::value,
+                  int>::type = 0>
+    constexpr span(const span<OtherElementType, OtherExtent>& other) noexcept
+        : storage_(other.data(), other.size())
+    {}
+
+    ~span() noexcept = default;
+
+    TCB_SPAN_CONSTEXPR_ASSIGN span&
+    operator=(const span& other) noexcept = default;
+
+    // [span.sub], span subviews
+    template <std::size_t Count>
+    TCB_SPAN_CONSTEXPR11 span<element_type, Count> first() const
+    {
+        TCB_SPAN_EXPECT(Count <= size());
+        return {data(), Count};
+    }
+
+    template <std::size_t Count>
+    TCB_SPAN_CONSTEXPR11 span<element_type, Count> last() const
+    {
+        TCB_SPAN_EXPECT(Count <= size());
+        return {data() + (size() - Count), Count};
+    }
+
+    template <std::size_t Offset, std::size_t Count = dynamic_extent>
+    using subspan_return_t =
+        span<ElementType, Count != dynamic_extent
+                              ? Count
+                              : (Extent != dynamic_extent ? Extent - Offset
+                                                          : dynamic_extent)>;
+
+    template <std::size_t Offset, std::size_t Count = dynamic_extent>
+    TCB_SPAN_CONSTEXPR11 subspan_return_t<Offset, Count> subspan() const
+    {
+        TCB_SPAN_EXPECT(Offset <= size() &&
+                        (Count == dynamic_extent || Offset + Count <= size()));
+        return {data() + Offset,
+                Count != dynamic_extent ? Count : size() - Offset};
+    }
+
+    TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent>
+    first(size_type count) const
+    {
+        TCB_SPAN_EXPECT(count <= size());
+        return {data(), count};
+    }
+
+    TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent>
+    last(size_type count) const
+    {
+        TCB_SPAN_EXPECT(count <= size());
+        return {data() + (size() - count), count};
+    }
+
+    TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent>
+    subspan(size_type offset, size_type count = dynamic_extent) const
+    {
+        TCB_SPAN_EXPECT(offset <= size() &&
+                        (count == dynamic_extent || offset + count <= size()));
+        return {data() + offset,
+                count == dynamic_extent ? size() - offset : count};
+    }
+
+    // [span.obs], span observers
+    constexpr size_type size() const noexcept { return storage_.size; }
+
+    constexpr size_type size_bytes() const noexcept
+    {
+        return size() * sizeof(element_type);
+    }
+
+    TCB_SPAN_NODISCARD constexpr bool empty() const noexcept
+    {
+        return size() == 0;
+    }
+
+    // [span.elem], span element access
+    TCB_SPAN_CONSTEXPR11 reference operator[](size_type idx) const
+    {
+        TCB_SPAN_EXPECT(idx < size());
+        return *(data() + idx);
+    }
+
+    TCB_SPAN_CONSTEXPR11 reference front() const
+    {
+        TCB_SPAN_EXPECT(!empty());
+        return *data();
+    }
+
+    TCB_SPAN_CONSTEXPR11 reference back() const
+    {
+        TCB_SPAN_EXPECT(!empty());
+        return *(data() + (size() - 1));
+    }
+
+    constexpr pointer data() const noexcept { return storage_.ptr; }
+
+    // [span.iterators], span iterator support
+    constexpr iterator begin() const noexcept { return data(); }
+
+    constexpr iterator end() const noexcept { return data() + size(); }
+
+    TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin() const noexcept
+    {
+        return reverse_iterator(end());
+    }
+
+    TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rend() const noexcept
+    {
+        return reverse_iterator(begin());
+    }
+
+private:
+    storage_type storage_{};
+};
+
+#ifdef TCB_SPAN_HAVE_DEDUCTION_GUIDES
+
+/* Deduction Guides */
+template <class T, size_t N>
+span(T (&)[N])->span<T, N>;
+
+template <class T, size_t N>
+span(std::array<T, N>&)->span<T, N>;
+
+template <class T, size_t N>
+span(const std::array<T, N>&)->span<const T, N>;
+
+template <class Container>
+span(Container&)->span<typename std::remove_reference<
+    decltype(*detail::data(std::declval<Container&>()))>::type>;
+
+template <class Container>
+span(const Container&)->span<const typename Container::value_type>;
+
+#endif // TCB_HAVE_DEDUCTION_GUIDES
+
+template <typename ElementType, std::size_t Extent>
+constexpr span<ElementType, Extent>
+make_span(span<ElementType, Extent> s) noexcept
+{
+    return s;
+}
+
+template <typename T, std::size_t N>
+constexpr span<T, N> make_span(T (&arr)[N]) noexcept
+{
+    return {arr};
+}
+
+template <typename T, std::size_t N>
+TCB_SPAN_ARRAY_CONSTEXPR span<T, N> make_span(std::array<T, N>& arr) noexcept
+{
+    return {arr};
+}
+
+template <typename T, std::size_t N>
+TCB_SPAN_ARRAY_CONSTEXPR span<const T, N>
+make_span(const std::array<T, N>& arr) noexcept
+{
+    return {arr};
+}
+
+template <typename Container>
+constexpr span<typename std::remove_reference<
+    decltype(*detail::data(std::declval<Container&>()))>::type>
+make_span(Container& cont)
+{
+    return {cont};
+}
+
+template <typename Container>
+constexpr span<const typename Container::value_type>
+make_span(const Container& cont)
+{
+    return {cont};
+}
+
+template <typename ElementType, std::size_t Extent>
+span<const byte, ((Extent == dynamic_extent) ? dynamic_extent
+                                             : sizeof(ElementType) * Extent)>
+as_bytes(span<ElementType, Extent> s) noexcept
+{
+    return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
+}
+
+template <
+    class ElementType, size_t Extent,
+    typename std::enable_if<!std::is_const<ElementType>::value, int>::type = 0>
+span<byte, ((Extent == dynamic_extent) ? dynamic_extent
+                                       : sizeof(ElementType) * Extent)>
+as_writable_bytes(span<ElementType, Extent> s) noexcept
+{
+    return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
+}
+
+template <std::size_t N, typename E, std::size_t S>
+constexpr auto get(span<E, S> s) -> decltype(s[N])
+{
+    return s[N];
+}
+
+} // namespace TCB_SPAN_NAMESPACE_NAME
+
+namespace std {
+
+template <typename ElementType, size_t Extent>
+class tuple_size<TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>>
+    : public integral_constant<size_t, Extent> {};
+
+template <typename ElementType>
+class tuple_size<TCB_SPAN_NAMESPACE_NAME::span<
+    ElementType, TCB_SPAN_NAMESPACE_NAME::dynamic_extent>>; // not defined
+
+template <size_t I, typename ElementType, size_t Extent>
+class tuple_element<I, TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>> {
+public:
+    static_assert(Extent != TCB_SPAN_NAMESPACE_NAME::dynamic_extent &&
+                      I < Extent,
+                  "");
+    using type = ElementType;
+};
+
+} // end namespace std
+
+#endif // TCB_SPAN_HPP_INCLUDED
diff --git a/tests/fff_print/test_print.cpp b/tests/fff_print/test_print.cpp
index 395f75841..d8ab5a3fa 100644
--- a/tests/fff_print/test_print.cpp
+++ b/tests/fff_print/test_print.cpp
@@ -62,7 +62,7 @@ SCENARIO("Print: Changing number of solid surfaces does not cause all surfaces t
         // Precondition: Ensure that the model has 2 solid top layers (39, 38)
         // and one solid bottom layer (0).
 		auto test_is_solid_infill = [&print](size_t obj_id, size_t layer_id) {
-		    const Layer &layer = *(print.objects().at(obj_id)->get_layer((int)layer_id));
+		    const Layer &layer = *print.objects()[obj_id]->get_layer((int)layer_id);
 		    // iterate over all of the regions in the layer
 		    for (const LayerRegion *region : layer.regions()) {
 		        // for each region, iterate over the fill surfaces
diff --git a/tests/fff_print/test_printobject.cpp b/tests/fff_print/test_printobject.cpp
index 8d322f58f..cbc47345c 100644
--- a/tests/fff_print/test_printobject.cpp
+++ b/tests/fff_print/test_printobject.cpp
@@ -18,7 +18,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") {
 				{ "layer_height", 		2 },
 	            { "nozzle_diameter", 	3 }
 	        });
-            ConstLayerPtrsAdaptor layers = print.objects().front()->layers();
+            SpanOfConstPtrs<Layer> layers = print.objects().front()->layers();
             THEN("The output vector has 10 entries") {
                 REQUIRE(layers.size() == 10);
             }
@@ -37,7 +37,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") {
 				{ "layer_height", 		10 },
 	            { "nozzle_diameter", 	11 }
 	        });
-            ConstLayerPtrsAdaptor layers = print.objects().front()->layers();
+            SpanOfConstPtrs<Layer> layers = print.objects().front()->layers();
 			THEN("The output vector has 3 entries") {
                 REQUIRE(layers.size() == 3);
             }
@@ -55,7 +55,7 @@ SCENARIO("PrintObject: object layer heights", "[PrintObject]") {
 				{ "layer_height", 		15 },
 	            { "nozzle_diameter", 	16 }
 	        });
-            ConstLayerPtrsAdaptor layers = print.objects().front()->layers();
+            SpanOfConstPtrs<Layer> layers = print.objects().front()->layers();
 			THEN("The output vector has 2 entries") {
                 REQUIRE(layers.size() == 2);
             }
diff --git a/tests/fff_print/test_support_material.cpp b/tests/fff_print/test_support_material.cpp
index c5087263c..0720b270c 100644
--- a/tests/fff_print/test_support_material.cpp
+++ b/tests/fff_print/test_support_material.cpp
@@ -27,7 +27,7 @@ SCENARIO("SupportMaterial: support_layers_z and contact_distance", "[SupportMate
 
 	auto check = [](Slic3r::Print &print, bool &first_support_layer_height_ok, bool &layer_height_minimum_ok, bool &layer_height_maximum_ok, bool &top_spacing_ok)
 	{
-        ConstSupportLayerPtrsAdaptor support_layers = print.objects().front()->support_layers();
+        SpanOfConstPtrs<SupportLayer> support_layers = print.objects().front()->support_layers();
 
 		first_support_layer_height_ok = support_layers.front()->print_z == print.config().first_layer_height.value;
 

From f57744ad129d9cb6dc845232b1c9f1ddc1b0ac0d Mon Sep 17 00:00:00 2001
From: Vojtech Bubnik <bubnikv@gmail.com>
Date: Wed, 19 Oct 2022 16:40:41 +0200
Subject: [PATCH 5/5] Follow-up to 2ced7629482ea0b0feab66906b6a97fe0d57b747    
 Integrating a C++20 like span library     https://github.com/tcbrindle/span

---
 src/CMakeLists.txt         | 1 -
 src/tcbspan/CMakeLists.txt | 6 ------
 2 files changed, 7 deletions(-)
 delete mode 100644 src/tcbspan/CMakeLists.txt

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1c1b16638..50eccfc84 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,7 +14,6 @@ add_subdirectory(libigl)
 add_subdirectory(hints)
 add_subdirectory(qoi)
 add_subdirectory(libnest2d)
-add_subdirectory(tcbspan)
 
 find_package(Qhull 7.2 REQUIRED)
 add_library(qhull INTERFACE)
diff --git a/src/tcbspan/CMakeLists.txt b/src/tcbspan/CMakeLists.txt
deleted file mode 100644
index 0668f838e..000000000
--- a/src/tcbspan/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12)
-project(tcbspan)
-
-add_library(tcbspan STATIC
-    span.hpp
-)