[gtkmm] Gtk::TextIter: Use sigc::slot in forward/backward_find_char()



commit b66d67d0d429af85228e0ba6ef2713697adf59ca
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Fri Jan 13 16:10:09 2017 +0100

    Gtk::TextIter: Use sigc::slot in forward/backward_find_char()
    
    A function pointer in a glib/gtk+ function is usually represented by
    a sigc::slot in the wrapping C++ method. Let's do that here, too.

 gtk/src/textiter.ccg |   53 ++++++++++++++++++-
 gtk/src/textiter.hg  |  148 ++++++++++++++++++++------------------------------
 2 files changed, 112 insertions(+), 89 deletions(-)
---
diff --git a/gtk/src/textiter.ccg b/gtk/src/textiter.ccg
index 1570514..6cecaf6 100644
--- a/gtk/src/textiter.ccg
+++ b/gtk/src/textiter.ccg
@@ -21,13 +21,64 @@
 #include <gtkmm/textmark.h>
 #include <gtkmm/textchildanchor.h>
 
+/**** Gtk::TextIterBase *******************************************************/
+
+namespace
+{
+gboolean TextIterBase_find_char_callback(gunichar ch, void* user_data)
+{
+  try
+  {
+    auto slot = static_cast<Gtk::TextIterBase::SlotFindChar*>(user_data);
+    return (*slot)(ch);
+  }
+  catch (...)
+  {
+    Glib::exception_handlers_invoke();
+    return false;
+  }
+}
+
+} // anonymous namespace
+
 namespace Gtk
 {
+bool TextIterBase::forward_find_char(const SlotFindChar& slot, const TextIterBase& limit)
+{
+  // Use the original slot (not a copy).
+  auto slot_copy = const_cast<SlotFindChar*>(&slot);
 
-/**** Gtk::TextIterBase *******************************************************/
+  return gtk_text_iter_forward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, limit.gobj());
+}
+
+bool TextIterBase::forward_find_char(const SlotFindChar& slot)
+{
+  // Use the original slot (not a copy).
+  auto slot_copy = const_cast<SlotFindChar*>(&slot);
+
+  return gtk_text_iter_forward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, nullptr);
+}
+
+bool TextIterBase::backward_find_char(const SlotFindChar& slot, const TextIterBase& limit)
+{
+  // Use the original slot (not a copy).
+  auto slot_copy = const_cast<SlotFindChar*>(&slot);
+
+  return gtk_text_iter_backward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, limit.gobj());
+}
+
+bool TextIterBase::backward_find_char(const SlotFindChar& slot)
+{
+  // Use the original slot (not a copy).
+  auto slot_copy = const_cast<SlotFindChar*>(&slot);
+
+  return gtk_text_iter_backward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, nullptr);
+}
 
 } // namespace Gtk
 
+/**** Gtk::TextIter and Gtk::TextConstIter ************************************/
+
 namespace Glib
 {
 // Can't have overloaded functions that differ only in return type.
diff --git a/gtk/src/textiter.hg b/gtk/src/textiter.hg
index e3afb84..056bc07 100644
--- a/gtk/src/textiter.hg
+++ b/gtk/src/textiter.hg
@@ -17,7 +17,6 @@
 
 #include <vector>
 #include <pangomm/language.h>
-#include <glibmm/exceptionhandler.h>
 #include <gtkmm/texttag.h>
 #include <gtk/gtk.h> /* we need the definition of GtkTextIter */
 
@@ -52,6 +51,7 @@ class TextIterBase
   _CLASS_BOXEDTYPE_STATIC(TextIterBase, GtkTextIter)
   _IGNORE(gtk_text_iter_copy, gtk_text_iter_free, gtk_text_iter_equal)
   _IGNORE(gtk_text_iter_assign)
+
 public:
   using iterator_category = std::bidirectional_iterator_tag;
   using value_type        = gunichar;
@@ -73,29 +73,6 @@ public:
     */
    explicit operator bool() const;
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-
-protected:
-  template <typename Predicate>
-  struct PredicateAdapter
-  {
-    Predicate predicate_;
-    inline explicit PredicateAdapter(const Predicate& predicate);
-    static gboolean gtk_callback(gunichar uc, void* user_data);
-  };
-
-  _WRAP_METHOD(bool forward_find_char_impl(GtkTextCharPredicate predicate,
-                                           void* user_data,
-                                           const GtkTextIter* limit), gtk_text_iter_forward_find_char)
-
-  _WRAP_METHOD(bool backward_find_char_impl(GtkTextCharPredicate predicate,
-                                            void* user_data,
-                                            const GtkTextIter* limit), gtk_text_iter_backward_find_char)
-
-#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
-public:
-
   _WRAP_METHOD(int get_offset() const, gtk_text_iter_get_offset)
   _WRAP_METHOD(int get_line() const, gtk_text_iter_get_line)
   _WRAP_METHOD(int get_line_offset() const, gtk_text_iter_get_line_offset)
@@ -191,14 +168,65 @@ public:
   _WRAP_METHOD(bool forward_to_tag_toggle(const Glib::RefPtr<const TextTag>& tag = Glib::RefPtr<const 
TextTag>()), gtk_text_iter_forward_to_tag_toggle)
   _WRAP_METHOD(bool backward_to_tag_toggle(const Glib::RefPtr<const TextTag>& tag = Glib::RefPtr<const 
TextTag>()), gtk_text_iter_backward_to_tag_toggle)
 
-  template <typename Predicate>
-  bool forward_find_char(const Predicate& predicate, const TextIterBase& limit);
-  template <typename Predicate>
-  bool forward_find_char(const Predicate& predicate);
-  template <typename Predicate>
-  bool backward_find_char(const Predicate& predicate, const TextIterBase& limit);
-  template <typename Predicate>
-  bool backward_find_char(const Predicate& predicate);
+  /** A slot that will be called on each consecutive character.
+   * forward_find_char() and backward_find_char() advance the iterator one
+   * character at a time until the slot returns <tt>true</tt>.
+   *
+   * For instance,
+   * @code
+   * bool on_find_char(gunichar ch);
+   * @endcode
+   *
+   * @newin{3,90}
+   */
+  using SlotFindChar = sigc::slot<bool(gunichar)>;
+
+  // _WRAP_METHOD can't be used here, because user_data is not the last parameter
+  // in the gtk+ functions.
+  //_WRAP_METHOD(bool forward_find_char(const SlotFindChar& slot{pred}, const TextIterBase& limit{.?}),
+  //  gtk_text_iter_forward_find_char, slot_name slot, slot_callback TextIterBase_find_char_callback, 
no_slot_copy)
+  //_WRAP_METHOD(bool backward_find_char(const SlotFindChar& slot{pred}, const TextIterBase& limit{.?}),
+  //  gtk_text_iter_backward_find_char, slot_name slot, slot_callback TextIterBase_find_char_callback, 
no_slot_copy)
+  _IGNORE(gtk_text_iter_forward_find_char, gtk_text_iter_backward_find_char)
+
+  /** Advances this iterator, calling @a slot on each character.
+   *
+   * If @a slot returns <tt>true</tt>, %forward_find_char() returns <tt>true</tt>
+   * and stops scanning.
+   * If @a slot never returns <tt>true</tt>, this iterator is set to @a limit.
+   *
+   * @param slot A function to be called on each character.
+   * @param limit Search limit.
+   * @return Whether a match was found.
+   */
+  bool forward_find_char(const SlotFindChar& slot, const TextIterBase& limit);
+
+  /** Advances this iterator, calling @a slot on each character.
+   *
+   * If @a slot returns <tt>true</tt>, %forward_find_char() returns <tt>true</tt>
+   * and stops scanning.
+   * If @a slot never returns <tt>true</tt>, this iterator is set to the end iterator.
+   *
+   * @param slot A function to be called on each character.
+   * @return Whether a match was found.
+   */
+  bool forward_find_char(const SlotFindChar& slot);
+
+  /** Same as forward_find_char(const SlotFindChar& slot, const TextIterBase& limit),
+   * but goes backward.
+   *
+   * @param slot Function to be called on each character.
+   * @param limit Search limit.
+   * @return Whether a match was found.
+   */
+  bool backward_find_char(const SlotFindChar& slot, const TextIterBase& limit);
+
+  /** Same as forward_find_char(const SlotFindChar& slot), but goes backward.
+   *
+   * @param slot Function to be called on each character.
+   * @return Whether a match was found.
+   */
+  bool backward_find_char(const SlotFindChar& slot);
 
   _WRAP_METHOD(int compare(const TextIterBase& rhs) const, gtk_text_iter_compare)
   _WRAP_METHOD(bool in_range(const TextIterBase& start, const TextIterBase& end) const, 
gtk_text_iter_in_range)
@@ -327,30 +355,6 @@ public:
 
 /**** Gtk::TextIterBase *******************************************************/
 
-template <typename Predicate> inline
-TextIterBase::PredicateAdapter<Predicate>::PredicateAdapter(const Predicate& predicate)
-:
-  predicate_(predicate)
-{}
-
-// static
-template <typename Predicate>
-gboolean TextIterBase::PredicateAdapter<Predicate>::gtk_callback(gunichar uc, void* user_data)
-{
-  try
-  {
-    // This will either use Predicate::operator(), or call a function pointer.
-    // The explicit conditional expression avoids relying on an implicit
-    // conversion of the return type to int, which might be not available.
-    return (static_cast<TextIterBase::PredicateAdapter<Predicate>*>(user_data)->predicate_(uc)) ? 1 : 0;
-  }
-  catch(...)
-  {
-    Glib::exception_handlers_invoke();
-    return 0;
-  }
-}
-
 inline
 TextIterBase::value_type TextIterBase::operator*() const
 {
@@ -363,38 +367,6 @@ TextIterBase::operator bool() const
   return !is_end();
 }
 
-template <typename Predicate>
-bool TextIterBase::forward_find_char(const Predicate& predicate, const TextIterBase& limit)
-{
-  typedef TextIterBase::PredicateAdapter<Predicate> PredAdapter;
-  PredAdapter adapter(predicate);
-  return this->forward_find_char_impl(&PredAdapter::gtk_callback, &adapter, limit.gobj());
-}
-
-template <typename Predicate>
-bool TextIterBase::forward_find_char(const Predicate& predicate)
-{
-  typedef TextIterBase::PredicateAdapter<Predicate> PredAdapter;
-  PredAdapter adapter(predicate);
-  return this->forward_find_char_impl(&PredAdapter::gtk_callback, &adapter, nullptr);
-}
-
-template <typename Predicate>
-bool TextIterBase::backward_find_char(const Predicate& predicate, const TextIterBase& limit)
-{
-  typedef TextIterBase::PredicateAdapter<Predicate> PredAdapter;
-  PredAdapter adapter(predicate);
-  return this->backward_find_char_impl(&PredAdapter::gtk_callback, &adapter, limit.gobj());
-}
-
-template <typename Predicate>
-bool TextIterBase::backward_find_char(const Predicate& predicate)
-{
-  typedef TextIterBase::PredicateAdapter<Predicate> PredAdapter;
-  PredAdapter adapter(predicate);
-  return this->backward_find_char_impl(&PredAdapter::gtk_callback, &adapter, nullptr);
-}
-
 /**** Gtk::TextIter ***********************************************************/
 
 inline


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