]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/list.cpp
Use std::unique_ptr for managing memory
[libs/gltk.git] / source / list.cpp
index 4b6854f72a91fd5cf1785af6adf2a76b70dc1b25..a028571c5a1eabd0f56c43a8367b65be7b8b048d 100644 (file)
@@ -20,15 +20,19 @@ incompatible_data::incompatible_data(const type_info &ti):
 { }
 
 
-List::List():
-       List(*new BasicListData<string>)
+List::List(unique_ptr<ListData> d):
+       List(*d)
 {
-       own_data = true;
+       own_data = move(d);
 }
 
+List::List():
+       List(make_unique<BasicListData<string>>())
+{ }
+
 List::List(ListData &d):
        data(&d),
-       observer(new DataObserver(*this))
+       observer(make_unique<DataObserver>(*this))
 {
        input_type = INPUT_NAVIGATION;
 
@@ -37,14 +41,6 @@ List::List(ListData &d):
        slider.signal_value_changed.connect(sigc::mem_fun(this, &List::slider_value_changed));
 }
 
-List::~List()
-{
-       delete item_factory;
-       delete observer;
-       if(own_data)
-               delete data;
-}
-
 void List::autosize_special(const Part &part, Geometry &ageom) const
 {
        if(part.get_name()=="items")
@@ -89,23 +85,16 @@ void List::set_data(ListData &d)
        if(item_factory)
                item_factory->set_data(d);
 
-       delete observer;
-       if(own_data)
-               delete data;
+       observer.reset();
+       own_data.reset();
 
        data = &d;
-       own_data = false;
-       observer = new DataObserver(*this);
+       observer = make_unique<DataObserver>(*this);
 
-       for(Item *i: items)
-               delete i;
        items.clear();
        size_t n_items = data->size();
        for(size_t i=0; i<n_items; ++i)
-       {
-               Item *item = create_item(i);
-               items.push_back(item);
-       }
+               items.emplace_back(create_item(i));
 
        items_changed();
 }
@@ -116,18 +105,18 @@ void List::items_changed()
        mark_rebuild();
 }
 
-List::Item *List::create_item(size_t index)
+unique_ptr<List::Item> List::create_item(size_t index)
 {
-       Item *item = nullptr;
+       unique_ptr<Item> item;
        if(item_factory)
                item = item_factory->create_item(index);
        else
-               item = new BasicItem(data->get_string(index));
+               item = make_unique<BasicItem>(data->get_string(index));
        if(index==sel_index)
                item->set_active(true);
        add(*item);
        item->autosize();
-       item->signal_autosize_changed.connect(sigc::bind(sigc::mem_fun(this, &List::item_autosize_changed), item));
+       item->signal_autosize_changed.connect(sigc::bind(sigc::mem_fun(this, &List::item_autosize_changed), item.get()));
        return item;
 }
 
@@ -170,7 +159,7 @@ void List::set_selected_index(size_t i)
        {
                items[sel_index]->set_active(true);
                if(state&FOCUS)
-                       set_input_focus(items[focus_index]);
+                       set_input_focus(items[focus_index].get());
                signal_item_selected.emit(sel_index);
        }
 }
@@ -178,7 +167,7 @@ void List::set_selected_index(size_t i)
 void List::set_selected_item(Widget *item)
 {
        for(size_t i=rows[first_row].first; (i<items.size() && items[i]->is_visible()); ++i)
-               if(item==items[i])
+               if(item==items[i].get())
                        return set_selected_index(i);
 }
 
@@ -305,7 +294,7 @@ void List::focus_in()
 {
        Container::focus_in();
        if(focus_index!=INVALID_INDEX && items[focus_index]->is_visible())
-               set_input_focus(items[focus_index]);
+               set_input_focus(items[focus_index].get());
        else
        {
                if(sel_index!=INVALID_INDEX && items[sel_index]->is_visible())
@@ -372,7 +361,7 @@ void List::set_focus_index(size_t i)
        {
                scroll_to_focus();
                if(state&FOCUS)
-                       set_input_focus(items[focus_index]);
+                       set_input_focus(items[focus_index].get());
        }
 }
 
@@ -533,8 +522,7 @@ void List::DataObserver::item_added(size_t i)
        adjust_index(list.sel_index, i, 1);
        adjust_index(list.focus_index, i, 1);
 
-       Item *item = list.create_item(i);
-       list.items.insert(list.items.begin()+i, item);
+       list.items.insert(list.items.begin()+i, list.create_item(i));
        list.items_changed();
 }
 
@@ -544,7 +532,6 @@ void List::DataObserver::item_removed(size_t i)
        adjust_index(list.sel_index, i, -1);
        adjust_index(list.focus_index, i, -1);
 
-       delete list.items[i];
        list.items.erase(list.items.begin()+i);
        list.items_changed();
 
@@ -556,8 +543,6 @@ void List::DataObserver::cleared()
 {
        list.sel_index = INVALID_INDEX;
        list.focus_index = INVALID_INDEX;
-       for(Item *i: list.items)
-               delete i;
        list.items.clear();
        list.items_changed();
 
@@ -566,9 +551,8 @@ void List::DataObserver::cleared()
 
 void List::DataObserver::refresh_item(size_t i)
 {
-       delete list.items[i];
-       // Avoid stale pointer while create_item is executing
-       list.items[i] = nullptr;
+       // Destroy the old item before calling create_item
+       list.items[i].reset();
        list.items[i] = list.create_item(i);
        list.items_changed();
 }
@@ -584,7 +568,7 @@ void List::Item::autosize_special(const Part &part, Geometry &ageom) const
        if(part.get_name()=="children")
        {
                const Sides &margin = part.get_margin();
-               for(const Child *c: children)
+               for(const unique_ptr<Child> &c: children)
                {
                        Geometry cgeom;
                        c->widget->autosize(cgeom);
@@ -603,7 +587,7 @@ void List::Item::render_special(const Part &part, GL::Renderer &renderer) const
 {
        if(part.get_name()=="children")
        {
-               for(const Child *c: children)
+               for(const unique_ptr<Child> &c: children)
                        c->widget->render(renderer);
        }
 }
@@ -630,7 +614,7 @@ void List::MultiColumnItem::check_widths(vector<unsigned> &widths) const
                widths.resize(children.size(), 0);
 
        size_t n = 0;
-       for(const Child *c: children)
+       for(const unique_ptr<Child> &c: children)
        {
                Geometry cgeom;
                c->widget->autosize(cgeom);
@@ -652,7 +636,7 @@ void List::MultiColumnItem::set_widths(const vector<unsigned> &widths)
        const Sides &margin = part->get_margin();
        int x = margin.left;
        size_t n = 0;
-       for(const Child *c: children)
+       for(const unique_ptr<Child> &c: children)
        {
                c->widget->set_position(x, margin.bottom);
                x += widths[n++];
@@ -664,14 +648,14 @@ void List::MultiColumnItem::on_style_change()
        if(!style)
                return;
 
-       for(const Child *c: children)
+       for(const unique_ptr<Child> &c: children)
                c->widget->autosize();
 
        vector<unsigned> widths;
        List *list = static_cast<List *>(parent);
-       for(Item *i: list->items)
-               if(i!=this)
-                       if(MultiColumnItem *mci = dynamic_cast<MultiColumnItem *>(i))
+       for(const unique_ptr<Item> &i: list->items)
+               if(i.get()!=this)
+                       if(MultiColumnItem *mci = dynamic_cast<MultiColumnItem *>(i.get()))
                                mci->check_widths(widths);
 
        vector<unsigned> self_widths(widths);
@@ -682,8 +666,8 @@ void List::MultiColumnItem::on_style_change()
 
        if(update_all)
        {
-               for(Item *i: list->items)
-                       if(MultiColumnItem *mci = dynamic_cast<MultiColumnItem *>(i))
+               for(const unique_ptr<Item> &i: list->items)
+                       if(MultiColumnItem *mci = dynamic_cast<MultiColumnItem *>(i.get()))
                                mci->set_widths(self_widths);
        }