[glom/no_raw_loops] no raw loops: Add string_join() and use it instead of for loops.



commit cbc0fec8d43211aa169307020a226117f987851f
Author: Murray Cumming <murrayc murrayc com>
Date:   Mon Jan 4 15:44:11 2016 +0100

    no raw loops: Add string_join() and use it instead of for loops.
    
    Inspired by Sean Parent's "no raw loops" idea:
     https://www.youtube.com/watch?v=qH6sSOr-yk8
    though I am not really convinced that this improves the code in this
    particular case. What we gain by having no for loop we lose by having the
    awkard lambda syntax. In Sean Parent's examples this is clearer because of
    the use of (I think) adaptors to refer to particular member fields.

 .../layout/report_parts/layoutitem_groupby.cc      |   16 +++----
 glom/libglom/utils.cc                              |   41 ++++++++------------
 glom/libglom/utils.h                               |   24 +++++++++++
 glom/mode_design/fields/dialog_fieldcalculation.cc |   19 +++++----
 4 files changed, 57 insertions(+), 43 deletions(-)
---
diff --git a/glom/libglom/data_structure/layout/report_parts/layoutitem_groupby.cc 
b/glom/libglom/data_structure/layout/report_parts/layoutitem_groupby.cc
index 37dceee..371c56b 100644
--- a/glom/libglom/data_structure/layout/report_parts/layoutitem_groupby.cc
+++ b/glom/libglom/data_structure/layout/report_parts/layoutitem_groupby.cc
@@ -20,6 +20,7 @@
  
 #include <libglom/data_structure/layout/report_parts/layoutitem_groupby.h>
 #include <libglom/data_structure/layout/layoutitem_field.h>
+#include <libglom/utils.h>
 #include <glibmm/i18n.h>
 
 namespace Glom
@@ -125,16 +126,13 @@ Glib::ustring LayoutItem_GroupBy::get_layout_display_name() const
   {
     result += "(sort by: ";
 
-    Glib::ustring sort_fields_names;
-
     //List all the sort fields:
-    for(const auto& sort_by : m_fields_sort_by)
-    {
-      if(!sort_fields_names.empty())
-        sort_fields_names += ", ";
-
-      sort_fields_names += sort_by.first->get_layout_display_name();
-    }
+    const auto sort_fields_names = Utils::string_join(m_fields_sort_by,
+      [](const auto& item)
+      {
+        return item.first->get_layout_display_name();
+      },
+      ", ");
 
     result += sort_fields_names + ')';
   }
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index 19827c7..518a081 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -1356,19 +1356,15 @@ std::string Utils::get_file_path_without_extension(const std::string& filepath)
 
 Glib::ustring Utils::get_list_of_layout_items_for_display(const LayoutGroup::type_list_items& 
list_layout_fields)
 {
-  Glib::ustring result;
-  for(const auto& item : list_layout_fields)
-  {
-    if(item)
+  return string_join(list_layout_fields,
+    [](const auto& item)
     {
-      if(!result.empty())
-       result += ", ";
-
-      result += item->get_layout_display_name();
-    }
-  }
+      if(!item)
+        return Glib::ustring();
 
-  return result;
+      return item->get_layout_display_name();
+    },
+    ", ");
 }
 
 Glib::ustring Utils::get_list_of_layout_items_for_display(const std::shared_ptr<const LayoutGroup>& 
layout_group)
@@ -1381,21 +1377,16 @@ Glib::ustring Utils::get_list_of_layout_items_for_display(const std::shared_ptr<
 
 Glib::ustring Utils::get_list_of_sort_fields_for_display(const Formatting::type_list_sort_fields& 
sort_fields)
 {
-  Glib::ustring text;
-  for(const auto& the_pair : sort_fields)
-  {
-    const auto item = the_pair.first;
-    if(!item)
-      continue;
-    
-    if(!text.empty())
-      text += ", ";
-
-    text += item->get_layout_display_name();
-    //TODO: Show Ascending/Descending?
-  }
+  return string_join(sort_fields,
+    [](const auto& item)
+    {
+      if(!item.first)
+        return Glib::ustring();
 
-  return text;
+      return item.first->get_layout_display_name();
+      //TODO: Show Ascending/Descending?
+    },
+    ", ");
 }
 
 std::string Utils::get_temp_file_path(const std::string& prefix, const std::string& extension)
diff --git a/glom/libglom/utils.h b/glom/libglom/utils.h
index 63e916d..19082df 100644
--- a/glom/libglom/utils.h
+++ b/glom/libglom/utils.h
@@ -173,6 +173,30 @@ Glib::ustring title_from_string(const Glib::ustring& text);
 typedef std::vector<Glib::ustring> type_vec_strings;
 type_vec_strings string_separate(const Glib::ustring& str, const Glib::ustring& separator, bool 
ignore_quoted_separator = false);
 
+template<class T_container, class T_functor>
+Glib::ustring string_join(const T_container& container, const T_functor& f, const Glib::ustring& delim = 
Glib::ustring())
+{
+  //We could do this like so, but std::boost::algorithm::join() is apparently hard-coded to use std::string,
+  //so it won't work with Glib::ustring.
+  //
+  // std::vector<Glib::ustring> display_names(m_fields_sort_by.size());
+  // std::transform(container.begin(), container.end(),
+  //  display_names.begin(), f);
+  // return boost::algorithm::join(display_names, delim);
+
+  Glib::ustring result;
+
+  for(const auto& thing : container)
+  {
+    if(!delim.empty() && !result.empty())
+      result += delim;
+
+    result += f(thing);
+  }
+
+  return result;
+}
+
 Glib::ustring string_trim(const Glib::ustring& str, const Glib::ustring& to_remove);
 
 Glib::ustring string_remove_suffix(const Glib::ustring& str, const Glib::ustring& suffix, bool 
case_sensitive = true);
diff --git a/glom/mode_design/fields/dialog_fieldcalculation.cc 
b/glom/mode_design/fields/dialog_fieldcalculation.cc
index 7a28239..0186011 100644
--- a/glom/mode_design/fields/dialog_fieldcalculation.cc
+++ b/glom/mode_design/fields/dialog_fieldcalculation.cc
@@ -154,16 +154,17 @@ void Dialog_FieldCalculation::on_button_test()
   layoutitem_temp->set_full_field_details(temp);
   const auto triggered_fields = get_calculation_fields(m_table_name, layoutitem_temp);
 
-  Glib::ustring field_names;
-  for(const auto& field : triggered_fields)
-  {
-    field_names += ( field->get_layout_display_name() + ", " );
-  }
+  auto field_names = Utils::string_join(triggered_fields,
+    [](const auto& field)
+    {
+      return field->get_layout_display_name() + ", ";
+    });
 
-  for(const auto& field : temp->get_calculation_relationships())
-  {
-    field_names += ( "related(" + field + "), " );
-  }
+  field_names += Utils::string_join(temp->get_calculation_relationships(),
+    [](const auto& field)
+    {
+      return "related(" + Glib::ustring(field) + "), ";
+    });
 
   m_label_triggered_by->set_text(field_names);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]