[glibmm] Glib: Add BasicStringView, StdStringView, UStringView



commit 8d1c0209be149e6d80e9043c95466795a9f62484
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Wed Oct 23 10:15:48 2019 +0200

    Glib: Add BasicStringView, StdStringView, UStringView
    
    and use them in build_filename() and other functions in miscutils.hg.
    
    Fixes #34

 glib/glibmm/ustring.h  |  47 +++++++++++++++
 glib/src/miscutils.ccg |  91 ++++-------------------------
 glib/src/miscutils.hg  | 155 +++++++------------------------------------------
 3 files changed, 79 insertions(+), 214 deletions(-)
---
diff --git a/glib/glibmm/ustring.h b/glib/glibmm/ustring.h
index a5bfca48..722fe77b 100644
--- a/glib/glibmm/ustring.h
+++ b/glib/glibmm/ustring.h
@@ -1562,6 +1562,53 @@ operator+(char lhs, const ustring& rhs)
   return temp;
 }
 
+//************* Glib::BasicStringView ********************
+
+// It would be possible to replace StdStringView and UStringView with one
+// non-template class StringView, having 3 constructors taking a const Glib::ustring&,
+// a const std::string& and a const char*, respectively. But such a StringView
+// would give no hint to users where to use Glib::ustring, and where to use std::string.
+/** Helper class to avoid unnecessary string copying in function calls.
+ *
+ * A %BasicStringView holds a const char pointer. It can be used as an argument
+ * type in a function that passes a const char pointer to a C function.
+ * @code
+ * // Use
+ * std::string f1(Glib::StdStringView s1, Glib::StdStringView s2);
+ * Glib::ustring f2(Glib::UStringView s1, Glib::UStringView s2);
+ * // instead of
+ * std::string f1(const std::string& s1, const std::string& s2);
+ * Glib::ustring f2(const Glib::ustring& s1, const Glib::ustring& s2);
+ * @endcode
+ * to avoid string copying when the functions are called with string literals.
+ * @code
+ * auto r1 = f1("string 1", "string 2");
+ * auto r2 = f2("string 3", "string 4");
+ * @endcode
+ *
+ * @newin{2,64}
+ */
+template <typename T>
+class BasicStringView
+{
+public:
+  BasicStringView(const T& s) : pstring_(s.c_str()) {}
+  BasicStringView(const char* s) : pstring_(s) {}
+  const char* c_str() const { return pstring_; }
+private:
+  const char* pstring_;
+};
+
+/** Recommended data types: std::string, const char*
+ * @relates Glib::BasicStringView
+ */
+using StdStringView = BasicStringView<std::string>;
+
+/** Recommended data types: Glib::ustring, const char*
+ * @relates Glib::BasicStringView
+ */
+using UStringView = BasicStringView<Glib::ustring>;
+
 } // namespace Glib
 
 #endif /* _GLIBMM_USTRING_H */
diff --git a/glib/src/miscutils.ccg b/glib/src/miscutils.ccg
index 5faa88f1..b32fe57a 100644
--- a/glib/src/miscutils.ccg
+++ b/glib/src/miscutils.ccg
@@ -31,7 +31,7 @@ get_application_name()
 }
 
 void
-set_application_name(const Glib::ustring& application_name)
+set_application_name(UStringView application_name)
 {
   g_set_application_name(application_name.c_str());
 }
@@ -43,13 +43,13 @@ get_prgname()
 }
 
 void
-set_prgname(const std::string& prgname)
+set_prgname(StdStringView prgname)
 {
   g_set_prgname(prgname.c_str());
 }
 
 std::string
-getenv(const std::string& variable, bool& found)
+getenv(StdStringView variable, bool& found)
 {
   const char* const value = g_getenv(variable.c_str());
   found = (value != nullptr);
@@ -57,19 +57,19 @@ getenv(const std::string& variable, bool& found)
 }
 
 std::string
-getenv(const std::string& variable)
+getenv(StdStringView variable)
 {
   return convert_const_gchar_ptr_to_stdstring(g_getenv(variable.c_str()));
 }
 
 bool
-setenv(const std::string& variable, const std::string& value, bool overwrite)
+setenv(StdStringView variable, StdStringView value, bool overwrite)
 {
   return g_setenv(variable.c_str(), value.c_str(), overwrite);
 }
 
 void
-unsetenv(const std::string& variable)
+unsetenv(StdStringView variable)
 {
   g_unsetenv(variable.c_str());
 }
@@ -159,13 +159,13 @@ get_user_runtime_dir()
 }
 
 bool
-path_is_absolute(const std::string& filename)
+path_is_absolute(StdStringView filename)
 {
-  return (g_path_is_absolute(filename.c_str()) != 0);
+  return g_path_is_absolute(filename.c_str()) != 0;
 }
 
 std::string
-path_skip_root(const std::string& filename)
+path_skip_root(StdStringView filename)
 {
   // g_path_skip_root() returns a pointer _into_ the argument string,
   // or NULL if there was no root component.
@@ -173,13 +173,13 @@ path_skip_root(const std::string& filename)
 }
 
 std::string
-path_get_basename(const std::string& filename)
+path_get_basename(StdStringView filename)
 {
   return convert_return_gchar_ptr_to_stdstring(g_path_get_basename(filename.c_str()));
 }
 
 std::string
-path_get_dirname(const std::string& filename)
+path_get_dirname(StdStringView filename)
 {
   return convert_return_gchar_ptr_to_stdstring(g_path_get_dirname(filename.c_str()));
 }
@@ -191,73 +191,6 @@ build_filename(const std::vector<std::string>& elements)
     
g_build_filenamev(const_cast<char**>(Glib::ArrayHandler<std::string>::vector_to_array(elements).data())));
 }
 
-std::string
-build_filename(const std::string& elem1, const std::string& elem2)
-{
-  return convert_return_gchar_ptr_to_stdstring(
-    g_build_filename(elem1.c_str(), elem2.c_str(), nullptr));
-}
-
-std::string
-build_filename(const std::string& elem1, const std::string& elem2, const std::string& elem3)
-{
-  return convert_return_gchar_ptr_to_stdstring(
-    g_build_filename(elem1.c_str(), elem2.c_str(), elem3.c_str(), nullptr));
-}
-
-std::string
-build_filename(const std::string& elem1, const std::string& elem2, const std::string& elem3,
-  const std::string& elem4)
-{
-  return convert_return_gchar_ptr_to_stdstring(
-    g_build_filename(elem1.c_str(), elem2.c_str(), elem3.c_str(), elem4.c_str(), nullptr));
-}
-
-std::string
-build_filename(const std::string& elem1, const std::string& elem2, const std::string& elem3,
-  const std::string& elem4, const std::string& elem5)
-{
-  return convert_return_gchar_ptr_to_stdstring(g_build_filename(
-    elem1.c_str(), elem2.c_str(), elem3.c_str(), elem4.c_str(), elem5.c_str(), nullptr));
-}
-
-std::string
-build_filename(const std::string& elem1, const std::string& elem2, const std::string& elem3,
-  const std::string& elem4, const std::string& elem5, const std::string& elem6)
-{
-  return convert_return_gchar_ptr_to_stdstring(g_build_filename(elem1.c_str(), elem2.c_str(),
-    elem3.c_str(), elem4.c_str(), elem5.c_str(), elem6.c_str(), nullptr));
-}
-
-std::string
-build_filename(const std::string& elem1, const std::string& elem2, const std::string& elem3,
-  const std::string& elem4, const std::string& elem5, const std::string& elem6,
-  const std::string& elem7)
-{
-  return convert_return_gchar_ptr_to_stdstring(g_build_filename(elem1.c_str(), elem2.c_str(),
-    elem3.c_str(), elem4.c_str(), elem5.c_str(), elem6.c_str(), elem7.c_str(), nullptr));
-}
-
-std::string
-build_filename(const std::string& elem1, const std::string& elem2, const std::string& elem3,
-  const std::string& elem4, const std::string& elem5, const std::string& elem6,
-  const std::string& elem7, const std::string& elem8)
-{
-  return convert_return_gchar_ptr_to_stdstring(
-    g_build_filename(elem1.c_str(), elem2.c_str(), elem3.c_str(), elem4.c_str(), elem5.c_str(),
-      elem6.c_str(), elem7.c_str(), elem8.c_str(), nullptr));
-}
-
-std::string
-build_filename(const std::string& elem1, const std::string& elem2, const std::string& elem3,
-  const std::string& elem4, const std::string& elem5, const std::string& elem6,
-  const std::string& elem7, const std::string& elem8, const std::string& elem9)
-{
-  return convert_return_gchar_ptr_to_stdstring(
-    g_build_filename(elem1.c_str(), elem2.c_str(), elem3.c_str(), elem4.c_str(), elem5.c_str(),
-      elem6.c_str(), elem7.c_str(), elem8.c_str(), elem9.c_str(), nullptr));
-}
-
 std::string
 build_path(const std::string& separator, const std::vector<std::string>& elements)
 {
@@ -266,7 +199,7 @@ build_path(const std::string& separator, const std::vector<std::string>& element
 }
 
 std::string
-find_program_in_path(const std::string& program)
+find_program_in_path(StdStringView program)
 {
   return convert_return_gchar_ptr_to_stdstring(g_find_program_in_path(program.c_str()));
 }
diff --git a/glib/src/miscutils.hg b/glib/src/miscutils.hg
index 71c785d4..390f203d 100644
--- a/glib/src/miscutils.hg
+++ b/glib/src/miscutils.hg
@@ -55,7 +55,7 @@ Glib::ustring get_application_name();
  *
  * @param application_name Localized name of the application.
  */
-void set_application_name(const Glib::ustring& application_name);
+void set_application_name(UStringView application_name);
 
 /** Gets the name of the program.
  *
@@ -73,7 +73,7 @@ std::string get_prgname();
 /** Sets the name of the program.
  * @param prgname The name of the program.
  */
-void set_prgname(const std::string& prgname);
+void set_prgname(StdStringView prgname);
 
 /** Returns the value of an environment variable. The name and value
  * are in the GLib file name encoding. On Unix, this means the actual
@@ -86,7 +86,7 @@ void set_prgname(const std::string& prgname);
  * @param[out] found Whether the environment variable has been found.
  * @return The value of the environment variable, or <tt>""</tt> if not found.
  */
-std::string getenv(const std::string& variable, bool& found);
+std::string getenv(StdStringView variable, bool& found);
 
 /** Returns the value of an environment variable. The name and value
  * are in the GLib file name encoding. On Unix, this means the actual
@@ -98,7 +98,7 @@ std::string getenv(const std::string& variable, bool& found);
  * @param variable The environment variable to get.
  * @return The value of the environment variable, or <tt>""</tt> if not found.
  */
-std::string getenv(const std::string& variable);
+std::string getenv(StdStringView variable);
 
 
 /** Sets an environment variable. Both the variable's name and value
@@ -114,7 +114,7 @@ std::string getenv(const std::string& variable);
  * @param overwrite Whether to change the variable if it already exists.
  * @result false if the environment variable couldn't be set.
  */
-bool setenv(const std::string& variable, const std::string& value, bool overwrite = true);
+bool setenv(StdStringView variable, StdStringView value, bool overwrite = true);
 
 /** Removes an environment variable from the environment.
  *
@@ -125,7 +125,7 @@ bool setenv(const std::string& variable, const std::string& value, bool overwrit
  *
  * @param variable: the environment variable to remove. It  must not contain '='.
  **/
-void unsetenv(const std::string& variable);
+void unsetenv(StdStringView variable);
 
 /** Gets the names of all variables set in the environment.
  *
@@ -276,7 +276,7 @@ std::string get_user_runtime_dir();
  * @param filename A file name.
  * @return Whether @a filename is an absolute path.
  */
-bool path_is_absolute(const std::string& filename);
+bool path_is_absolute(StdStringView filename);
 
 /** Returns the remaining part of @a filename after the root component,
  * i.e.\ after the <tt>"/"</tt> on UNIX or <tt>"C:\\"</tt> on Windows.
@@ -284,20 +284,20 @@ bool path_is_absolute(const std::string& filename);
  * @param filename A file name.
  * @return The file name without the root component, or <tt>""</tt>.
  */
-std::string path_skip_root(const std::string& filename);
+std::string path_skip_root(StdStringView filename);
 
 /** Gets the name of the file without any leading directory components.
  * @param filename The name of the file.
  * @return The name of the file without any leading directory components.
  */
-std::string path_get_basename(const std::string& filename);
+std::string path_get_basename(StdStringView filename);
 
 /** Gets the directory components of a file name.
  * If the file name has no directory components <tt>"."</tt> is returned.
  * @param filename The name of the file.
  * @return The directory components of the file.
  */
-std::string path_get_dirname(const std::string& filename);
+std::string path_get_dirname(StdStringView filename);
 
 /** Creates a filename from a series of elements using the correct
  * separator for filenames.
@@ -310,134 +310,19 @@ std::string path_get_dirname(const std::string& filename);
  */
 std::string build_filename(const std::vector<std::string>&  elements);
 
-/** Creates a filename from two elements using the correct separator for filenames.
+/** Creates a filename from one or more elements using the correct separator for filenames.
  * No attempt is made to force the resulting filename to be an absolute path.
  * If the first element is a relative path, the result will be a relative path.
- * @param elem1 First path element.
- * @param elem2 Second path element.
+ * @tparam Strings std::string or const char*.
+ * @param strings The path elements.
  * @return The resulting path.
  */
-std::string build_filename(const std::string& elem1, const std::string& elem2);
-
-/** Creates a filename from three elements using the correct separator for filenames.
- * No attempt is made to force the resulting filename to be an absolute path.
- * If the first element is a relative path, the result will be a relative path.
- * @param elem1 First path element.
- * @param elem2 Second path element.
- * @param elem3 Third path element.
- * @return The resulting path.
- *
- * @newin{2,28}
- */
-std::string build_filename(const std::string& elem1, const std::string& elem2,
-                           const std::string& elem3);
-
-
-/** Creates a filename from four elements using the correct separator for filenames.
- * No attempt is made to force the resulting filename to be an absolute path.
- * If the first element is a relative path, the result will be a relative path.
- * @param elem1 First path element.
- * @param elem2 Second path element.
- * @param elem3 Third path element.
- * @param elem4 Fourth path element.
- * @return The resulting path.
- *
- * @newin{2,28}
- */
-std::string build_filename(const std::string& elem1, const std::string& elem2,
-                           const std::string& elem3, const std::string& elem4);
-
-/** Creates a filename from five elements using the correct separator for filenames.
- * No attempt is made to force the resulting filename to be an absolute path.
- * If the first element is a relative path, the result will be a relative path.
- * @param elem1 First path element.
- * @param elem2 Second path element.
- * @param elem3 Third path element.
- * @param elem4 Fourth path element.
- * @param elem5 Fifth path element.
- * @return The resulting path.
- */
-std::string build_filename(const std::string& elem1, const std::string& elem2,
-                           const std::string& elem3, const std::string& elem4,
-                           const std::string& elem5);
-
-/** Creates a filename from six elements using the correct separator for filenames.
- * No attempt is made to force the resulting filename to be an absolute path.
- * If the first element is a relative path, the result will be a relative path.
- * @param elem1 First path element.
- * @param elem2 Second path element.
- * @param elem3 Third path element.
- * @param elem4 Fourth path element.
- * @param elem5 Fifth path element.
- * @param elem6 Sixth path element.
- * @return The resulting path.
- *
- * @newin{2,28}
- */
-std::string build_filename(const std::string& elem1, const std::string& elem2,
-                           const std::string& elem3, const std::string& elem4,
-                           const std::string& elem5, const std::string& elem6);
-
-/** Creates a filename from seven elements using the correct separator for filenames.
- * No attempt is made to force the resulting filename to be an absolute path.
- * If the first element is a relative path, the result will be a relative path.
- * @param elem1 First path element.
- * @param elem2 Second path element.
- * @param elem3 Third path element.
- * @param elem4 Fourth path element.
- * @param elem5 Fifth path element.
- * @param elem6 Sixth path element.
- * @param elem7 Seventh path element.
- * @return The resulting path.
- *
- * @newin{2,28}
- */
-std::string build_filename(const std::string& elem1, const std::string& elem2,
-                           const std::string& elem3, const std::string& elem4,
-                           const std::string& elem5, const std::string& elem6,
-                           const std::string& elem7);
-
-/** Creates a filename from eight elements using the correct separator for filenames.
- * No attempt is made to force the resulting filename to be an absolute path.
- * If the first element is a relative path, the result will be a relative path.
- * @param elem1 First path element.
- * @param elem2 Second path element.
- * @param elem3 Third path element.
- * @param elem4 Fourth path element.
- * @param elem5 Fifth path element.
- * @param elem6 Sixth path element.
- * @param elem7 Seventh path element.
- * @param elem8 Eighth path element.
- * @return The resulting path.
- *
- * @newin{2,28}
- */
-std::string build_filename(const std::string& elem1, const std::string& elem2,
-                           const std::string& elem3, const std::string& elem4,
-                           const std::string& elem5, const std::string& elem6,
-                           const std::string& elem7, const std::string& elem8);
-
-/** Creates a filename from nine elements using the correct separator for filenames.
- * No attempt is made to force the resulting filename to be an absolute path.
- * If the first element is a relative path, the result will be a relative path.
- * @param elem1 First path element.
- * @param elem2 Second path element.
- * @param elem3 Third path element.
- * @param elem4 Fourth path element.
- * @param elem5 Fifth path element.
- * @param elem6 Sixth path element.
- * @param elem7 Seventh path element.
- * @param elem8 Eighth path element.
- * @param elem9 Ninth path element.
- * @return The resulting path.
- *
- * @newin{2,28}
- */
-std::string build_filename(const std::string& elem1, const std::string& elem2,
-                           const std::string& elem3, const std::string& elem4,
-                           const std::string& elem5, const std::string& elem6,
-                           const std::string& elem7, const std::string& elem8,
-                           const std::string& elem9);
+template <typename... Strings>
+std::string build_filename(const Strings&... strings)
+{
+  return Glib::convert_return_gchar_ptr_to_stdstring(
+    g_build_filename(StdStringView(strings).c_str()..., nullptr));
+}
 
 /** Creates a path from a series of elements using @a separator as the
  * separator between elements.
@@ -495,7 +380,7 @@ std::string build_path(const std::string& separator,
  * @param program A program name.
  * @return An absolute path, or <tt>""</tt>.
  */
-std::string find_program_in_path(const std::string& program);
+std::string find_program_in_path(StdStringView program);
 
 /** Formats a size (for example the size of a file) into a human readable string.
  *


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