]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/layout.cpp
Convert loops and iterators to use C++11 features
[libs/gltk.git] / source / layout.cpp
index 1cf35c722a3a95476532ec1d35898aa7a0e5b903..200801f36285b7c3d9ed55402fd764a27f0a8813 100644 (file)
@@ -1,5 +1,5 @@
-#include <algorithm>
 #include <limits>
+#include <msp/core/algorithm.h>
 #include <msp/core/maputils.h>
 #include <msp/strings/format.h>
 #include "arrangement.h"
@@ -98,8 +98,8 @@ Layout::Layout():
 
 Layout::~Layout()
 {
-       for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
-               delete *i;
+       for(Slot *s: slots)
+               delete s;
 }
 
 void Layout::set_container(Container &c)
@@ -154,7 +154,7 @@ Arrangement *Layout::get_arrangement() const
 
 void Layout::pop_arrangement(Arrangement &arr)
 {
-       list<Arrangement *>::iterator begin = find(arrangement_stack.begin(), arrangement_stack.end(), &arr);
+       auto begin = find(arrangement_stack, &arr);
        if(begin==arrangement_stack.end())
                return;
 
@@ -184,71 +184,70 @@ void Layout::add_widget(Widget &wdg)
 
 void Layout::remove_widget(Widget &wdg)
 {
-       for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
-               if(&(*i)->widget==&wdg)
+       auto i = find_if(slots, [&wdg](Slot *s){ return &s->widget==&wdg; });
+       if(i==slots.end())
+               return;
+
+       for(Slot *s: slots)
+               if(s!=*i)
                {
-                       for(list<Slot *>::iterator j=slots.begin(); j!=slots.end(); ++j)
-                               if(j!=i)
-                               {
-                                       for(list<Constraint>::iterator k=(*j)->constraints.begin(); k!=(*j)->constraints.end(); )
-                                       {
-                                               if(&k->target==*i)
-                                                       (*j)->constraints.erase(k++);
-                                               else
-                                                       ++k;
-                                       }
-                               }
+                       for(auto k=s->constraints.begin(); k!=s->constraints.end(); )
+                       {
+                               if(&k->target==*i)
+                                       s->constraints.erase(k++);
+                               else
+                                       ++k;
+                       }
+               }
 
-                       delete *i;
-                       slots.erase(i);
+       delete *i;
+       slots.erase(i);
 
-                       update_slot_indices();
-                       update();
-                       return;
-               }
+       update_slot_indices();
+       update();
 }
 
 void Layout::update_slot_indices()
 {
        n_active_slots = 0;
        unsigned n_floating = 0;
-       for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
+       for(Slot *s: slots)
        {
-               if((*i)->widget.is_visible() || (*i)->ghost)
+               if(s->widget.is_visible() || s->ghost)
                {
-                       (*i)->index = n_active_slots++;
-                       if((*i)->floating)
+                       s->index = n_active_slots++;
+                       if(s->floating)
                                ++n_floating;
                }
                else
-                       (*i)->index = -1;
+                       s->index = -1;
        }
 
        n_slack_vars[0] = n_floating*2;
        n_slack_vars[1] = n_floating*2;
-       for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
-               if((*i)->index>=0)
+       for(const Slot *s: slots)
+               if(s->index>=0)
                {
-                       if(!(*i)->floating)
+                       if(!s->floating)
                        {
                                for(unsigned j=0; j<2; ++j)
-                                       if(((*i)->*(pointers[j].packing)).gravity==0)
+                                       if((s->*(pointers[j].packing)).gravity==0)
                                                n_slack_vars[j] += 2;
                        }
 
-                       for(list<Constraint>::iterator j=(*i)->constraints.begin(); j!=(*i)->constraints.end(); ++j)
-                               if(j->target.index>(*i)->index && (j->type&SLACK))
-                                       ++n_slack_vars[j->type&1];
+                       for(const Constraint &c: s->constraints)
+                               if(c.target.index>s->index && (c.type&SLACK))
+                                       ++n_slack_vars[c.type&1];
                }
 }
 
 Layout::Slot &Layout::get_slot_for_widget(Widget &wdg)
 {
-       for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
-               if(&(*i)->widget==&wdg)
-                       return **i;
+       auto i = find_if(slots, [&wdg](const Slot *s){ return &s->widget==&wdg; });
+       if(i==slots.end())
+               throw hierarchy_error("widget not in layout");
 
-       throw hierarchy_error("widget not in layout");
+       return **i;
 }
 
 Layout::ConstraintType Layout::complement(ConstraintType type)
@@ -264,8 +263,8 @@ void Layout::create_constraint(Widget &src, ConstraintType type, Widget &tgt, in
        Slot &src_slot = get_slot_for_widget(src);
        Slot &tgt_slot = get_slot_for_widget(tgt);
 
-       for(list<Constraint>::iterator i=src_slot.constraints.begin(); i!=src_slot.constraints.end(); ++i)
-               if(i->type==type && &i->target==&tgt_slot)
+       for(const Constraint &c: src_slot.constraints)
+               if(c.type==type && &c.target==&tgt_slot)
                        return;
 
        src_slot.constraints.push_back(Constraint(type, tgt_slot));
@@ -336,8 +335,8 @@ void Layout::update()
        solve_constraints(HORIZONTAL, UPDATE);
        solve_constraints(VERTICAL, UPDATE);
 
-       for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
-               (*i)->widget.set_geometry((*i)->geom);
+       for(const Slot *s: slots)
+               s->widget.set_geometry(s->geom);
 }
 
 void Layout::autosize(Geometry &geom)
@@ -364,29 +363,29 @@ void Layout::solve_constraints(int dir, SolveMode mode)
        LinearProgram linprog(n_active_slots*5+n_slack_vars[dir]+1);
        float weight = slots.size()+1;
        unsigned k = n_active_slots*5;
-       for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
+       for(const Slot *s: slots)
        {
-               if((*i)->index<0)
+               if(s->index<0)
                        continue;
 
                LinearProgram::Row objective = linprog.get_objective_row();
                if(mode==AUTOSIZE)
                {
-                       objective[(*i)->index*5] = -1;
-                       objective[(*i)->index*5+1] = -1;
+                       objective[s->index*5] = -1;
+                       objective[s->index*5+1] = -1;
                }
                else
                {
-                       if(!(*i)->floating)
-                               objective[(*i)->index*5] = ((*i)->*(ptrs.packing)).gravity/weight;
-                       objective[(*i)->index*5+1] = (((*i)->*(ptrs.packing)).expand ? weight : -1);
+                       if(!s->floating)
+                               objective[s->index*5] = (s->*(ptrs.packing)).gravity/weight;
+                       objective[s->index*5+1] = ((s->*(ptrs.packing)).expand ? weight : -1);
                }
 
                {
                        // Prevent the widget from going past the container's low edge.
                        LinearProgram::Row row = linprog.add_row();
-                       row[(*i)->index*5] = 1;
-                       row[(*i)->index*5+2] = -1;
+                       row[s->index*5] = 1;
+                       row[s->index*5+2] = -1;
                        row.back() = margin.*(ptrs.low_margin);
                }
 
@@ -394,26 +393,26 @@ void Layout::solve_constraints(int dir, SolveMode mode)
                {
                        // Prevent the widget from going past the container's high edge.
                        LinearProgram::Row row = linprog.add_row();
-                       row[(*i)->index*5] = 1;
-                       row[(*i)->index*5+1] = 1;
-                       row[(*i)->index*5+3] = 1;
+                       row[s->index*5] = 1;
+                       row[s->index*5+1] = 1;
+                       row[s->index*5+3] = 1;
                        row.back() = geom.*(ptrs.dim)-margin.*(ptrs.high_margin);
                }
 
-               if((*i)->floating || ((*i)->*(ptrs.packing)).gravity==0)
+               if(s->floating || (s->*(ptrs.packing)).gravity==0)
                {
                        /* Try to keep the widget as close to a target position as possible.
                        Since linear programs can't express absolute values directly, use two
                        opposing slack variables that are optimized for a low value. */
-                       float a = ((*i)->*(ptrs.packing)).gravity*0.5+0.5;
+                       float a = (s->*(ptrs.packing)).gravity*0.5+0.5;
                        LinearProgram::Row row = linprog.add_row();
-                       row[(*i)->index*5] = 1;
-                       row[(*i)->index*5+1] = a;
+                       row[s->index*5] = 1;
+                       row[s->index*5+1] = a;
                        row[k] = 1;
                        row[k+1] = -1;
-                       if((*i)->floating)
+                       if(s->floating)
                        {
-                               const Geometry &cgeom = (*i)->widget.get_geometry();
+                               const Geometry &cgeom = s->widget.get_geometry();
                                row.back() = cgeom.*(ptrs.pos)+cgeom.*(ptrs.dim)*a;
                        }
                        else
@@ -427,30 +426,30 @@ void Layout::solve_constraints(int dir, SolveMode mode)
                        /* Don't allow the widget's dimension to get below that determined
                        by autosizing. */
                        LinearProgram::Row row = linprog.add_row();
-                       row[(*i)->index*5+1] = 1;
-                       row[(*i)->index*5+4] = -1;
-                       row.back() = (*i)->autosize_geom.*(ptrs.dim);
+                       row[s->index*5+1] = 1;
+                       row[s->index*5+4] = -1;
+                       row.back() = s->autosize_geom.*(ptrs.dim);
                }
 
                /* Add rows for user-defined constraints.  Constraints are always added
                in pairs, so it's only necessary to create a row for one half. */
-               for(list<Constraint>::iterator j=(*i)->constraints.begin(); j!=(*i)->constraints.end(); ++j)
-                       if(j->target.index>(*i)->index && (j->type&1)==dir)
+               for(const Constraint &c: s->constraints)
+                       if(c.target.index>s->index && (c.type&1)==dir)
                        {
                                LinearProgram::Row row = linprog.add_row();
-                               float polarity = ((j->type&SELF_DIM) ? -1 : 1);
-                               float dim_weight = ((j->type&HALF_DIM) ? 0.5f : 1);
-                               if(j->type&SELF_POS)
-                                       row[(*i)->index*5] = polarity;
-                               if(j->type&SELF_DIM)
-                                       row[(*i)->index*5+1] = polarity*dim_weight;
-                               if(j->type&TARGET_POS)
-                                       row[j->target.index*5] = -polarity;
-                               if(j->type&TARGET_DIM)
-                                       row[j->target.index*5+1] = -polarity*dim_weight;
-                               if(j->type&SPACING)
-                                       row.back() = (j->spacing>=0 ? j->spacing : this->*(ptrs.spacing));
-                               if(j->type&SLACK)
+                               float polarity = ((c.type&SELF_DIM) ? -1 : 1);
+                               float dim_weight = ((c.type&HALF_DIM) ? 0.5f : 1);
+                               if(c.type&SELF_POS)
+                                       row[s->index*5] = polarity;
+                               if(c.type&SELF_DIM)
+                                       row[s->index*5+1] = polarity*dim_weight;
+                               if(c.type&TARGET_POS)
+                                       row[c.target.index*5] = -polarity;
+                               if(c.type&TARGET_DIM)
+                                       row[c.target.index*5+1] = -polarity*dim_weight;
+                               if(c.type&SPACING)
+                                       row.back() = (c.spacing>=0 ? c.spacing : this->*(ptrs.spacing));
+                               if(c.type&SLACK)
                                        row[k++] = -1;
                        }
        }
@@ -461,20 +460,20 @@ void Layout::solve_constraints(int dir, SolveMode mode)
        if(mode==AUTOSIZE)
        {
                autosize_geom.*(ptrs.dim) = 0;
-               for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
-                       if((*i)->index>=0)
+               for(const Slot *s: slots)
+                       if(s->index>=0)
                        {
-                               int high_edge = linprog.get_variable((*i)->index*5)+linprog.get_variable((*i)->index*5+1);
+                               int high_edge = linprog.get_variable(s->index*5)+linprog.get_variable(s->index*5+1);
                                autosize_geom.*(ptrs.dim) = max(autosize_geom.*(ptrs.dim), high_edge+margin.*(ptrs.high_margin));
                        }
        }
        else
        {
-               for(list<Slot *>::iterator i=slots.begin(); i!=slots.end(); ++i)
-                       if((*i)->index>=0)
+               for(Slot *s: slots)
+                       if(s->index>=0)
                        {
-                               (*i)->geom.*(ptrs.pos) = linprog.get_variable((*i)->index*5);
-                               (*i)->geom.*(ptrs.dim) = linprog.get_variable((*i)->index*5+1);
+                               s->geom.*(ptrs.pos) = linprog.get_variable(s->index*5);
+                               s->geom.*(ptrs.dim) = linprog.get_variable(s->index*5+1);
                        }
        }
 }
@@ -728,31 +727,29 @@ void Layout::LinearProgram::prepare_columns()
        vector<float> obj_coeff(n_rows, 0.0f);
        vector<float> row_coeff(n_rows, 1.0f);
        const vector<float> &constants = columns.back().values;
-       for(vector<Column>::iterator i=columns.begin(); i!=columns.end(); ++i)
-       {
-               if(i->values.size()>=2 && i->values.back()!=0.0f && (constants.size()<i->values.size() || i->values.back()*constants[i->values.size()-1]>=0.0f) && obj_coeff[i->values.size()-1]==0.0f)
+       for(Column &c: columns)
+               if(c.values.size()>=2 && c.values.back()!=0.0f && (constants.size()<c.values.size() || c.values.back()*constants[c.values.size()-1]>=0.0f) && obj_coeff[c.values.size()-1]==0.0f)
                {
                        bool basic = true;
-                       for(unsigned j=1; (basic && j+1<i->values.size()); ++j)
-                               basic = (i->values[j]==0.0f);
+                       for(unsigned j=1; (basic && j+1<c.values.size()); ++j)
+                               basic = (c.values[j]==0.0f);
                        if(basic)
                        {
-                               i->basic = i->values.size()-1;
-                               row_coeff[i->basic] = 1.0f/i->values.back();
-                               obj_coeff[i->basic] = -i->values.front();
-                               i->values.clear();
+                               c.basic = c.values.size()-1;
+                               row_coeff[c.basic] = 1.0f/c.values.back();
+                               obj_coeff[c.basic] = -c.values.front();
+                               c.values.clear();
                        }
                }
-       }
 
        // Price out the newly-created basic variables.
-       for(vector<Column>::iterator i=columns.begin(); i!=columns.end(); ++i)
-               if(!i->values.empty())
+       for(Column &c: columns)
+               if(!c.values.empty())
                {
-                       for(unsigned j=0; j<i->values.size(); ++j)
+                       for(unsigned j=0; j<c.values.size(); ++j)
                        {
-                               i->values[j] *= row_coeff[j];
-                               i->values.front() += obj_coeff[j]*i->values[j];
+                               c.values[j] *= row_coeff[j];
+                               c.values.front() += obj_coeff[j]*c.values[j];
                        }
                }
 }
@@ -763,28 +760,28 @@ void Layout::LinearProgram::add_artificial_variables()
        for(unsigned i=0; i<artificial_rows.size(); ++i)
                artificial_rows[i] = i+1;
 
-       for(vector<Column>::iterator i=columns.begin(); i!=columns.end(); ++i)
-               if(i->basic)
-                       artificial_rows[i->basic-1] = 0;
+       for(const Column &c: columns)
+               if(c.basic)
+                       artificial_rows[c.basic-1] = 0;
        artificial_rows.erase(std::remove(artificial_rows.begin(), artificial_rows.end(), 0), artificial_rows.end());
 
        /* Force all non-basic columns fully into existence and relocate objective
        row to bottom in preparation of phase 1.  A new objective row is calculated
        by pricing out the constraint rows. */
-       for(vector<Column>::iterator i=columns.begin(); i!=columns.end(); ++i)
-               if(!i->basic)
+       for(Column &c: columns)
+               if(!c.basic)
                {
                        float objective = 0.0f;
-                       if(!i->values.empty())
+                       if(!c.values.empty())
                        {
-                               objective = i->values.front();
-                               i->values.front() = 0.0f;
-                               for(vector<unsigned>::iterator j=artificial_rows.begin(); j!=artificial_rows.end(); ++j)
-                                       if(*j<i->values.size())
-                                               i->values.front() += i->values[*j];
+                               objective = c.values.front();
+                               c.values.front() = 0.0f;
+                               for(unsigned r: artificial_rows)
+                                       if(r<c.values.size())
+                                               c.values.front() += c.values[r];
                        }
-                       i->values.resize(n_rows+1, 0.0f);
-                       i->values.back() = objective;
+                       c.values.resize(n_rows+1, 0.0f);
+                       c.values.back() = objective;
                }
 
        if(artificial_rows.empty())
@@ -821,11 +818,11 @@ void Layout::LinearProgram::remove_artificial_variables()
        /* Get rid of the artificial variables and restore the original objective
        row to form the phase 2 problem. */
        columns.erase(columns.begin()+(n_columns-1), columns.end()-1);
-       for(vector<Column>::iterator i=columns.begin(); i!=columns.end(); ++i)
-               if(!i->basic)
+       for(Column &c: columns)
+               if(!c.basic)
                {
-                       i->values.front() = i->values.back();
-                       i->values.pop_back();
+                       c.values.front() = c.values.back();
+                       c.values.pop_back();
                }
 }