[vte/wip/c++ify: 2/2] lib: Add grid coordinate and span types



commit fdb1ef3ef2469cd87e9a400385b2f0cbfc20bca8
Author: Christian Persch <chpe gnome org>
Date:   Tue Oct 20 15:26:22 2015 +0200

    lib: Add grid coordinate and span types
    
    Add vte::grid:coords to hold a (column, row) pair, and vte::grid::span
    to hold a pair of (start, end) coordinates.
    
    They will be used to replace passing separate (column, row) pairs around
    in arguments and data structures.
    
    Also contains tests for the member functions, and static assertion
    to test the size of these structs, and ensure they are and stay POD.

 src/Makefile.am |   36 ++++++++++-
 src/vtetypes.cc |  189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/vtetypes.hh |   83 ++++++++++++++++++++++++
 3 files changed, 306 insertions(+), 2 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 224df5b..5fd93fb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -337,7 +337,16 @@ noinst_PROGRAMS += interpret slowcat
 noinst_SCRIPTS = decset osc window
 EXTRA_DIST += $(noinst_SCRIPTS)
 
-check_PROGRAMS = dumpkeys reflect-text-view reflect-vte mev table xticker vteconv vtestream-file
+check_PROGRAMS = \
+       dumpkeys \
+       reflect-text-view \
+       reflect-vte mev \
+       table \
+       xticker \
+       vteconv \
+       vtestream-file \
+       test-vtetypes \
+       $(NULL)
 
 dist_check_SCRIPTS = \
        check-doc-syntax.sh \
@@ -345,7 +354,14 @@ dist_check_SCRIPTS = \
        test-vte-sh.sh \
        $(NULL)
 
-TESTS = table vteconv vtestream-file $(dist_check_SCRIPTS)
+TESTS = \
+       table \
+       test-vtetypes \
+       vteconv \
+       vtestream-file \
+       $(dist_check_SCRIPTS) \
+       $(NULL)
+
 TESTS_ENVIRONMENT = \
        srcdir="$(srcdir)" \
        top_builddir="$(top_builddir)" \
@@ -431,6 +447,22 @@ table_LDADD = \
        $(GLIB_LIBS) \
        $(GOBJECT_LIBS)
 
+test_vtetypes_SOURCES = \
+       vtetypes.cc \
+       vtetypes.hh \
+       $(NULL)
+test_vtetypes_CPPFLAGS = \
+       -DMAIN \
+       -I$(srcdir) \
+       -I$(builddir) \
+       $(AM_CPPFLAGS)
+test_vtetypes_CXXFLAGS = \
+       $(GLIB_CFLAGS) \
+       $(AM_CXXFLAGS)
+test_vtetypes_LDADD = \
+       $(GLIB_LIBS) \
+       $(NULL)
+
 vtestream_file_SOURCES = \
        vtestream-base.h \
        vtestream-file.h \
diff --git a/src/vtetypes.cc b/src/vtetypes.cc
new file mode 100644
index 0000000..5d56bfe
--- /dev/null
+++ b/src/vtetypes.cc
@@ -0,0 +1,189 @@
+/*
+ * Copyright © 2015 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "vtetypes.hh"
+
+#include <type_traits>
+
+static_assert(std::is_pod<vte::grid::coords>::value, "vte::grid::coords not POD");
+static_assert(sizeof(vte::grid::coords) == 2 * sizeof(long), "vte::grid::coords size wrong");
+
+static_assert(std::is_pod<vte::grid::span>::value, "vte::grid::span not POD");
+static_assert(sizeof(vte::grid::span) == 4 * sizeof(long), "vte::grid::span size wrong");
+
+
+#ifdef MAIN
+
+#include <glib.h>
+
+using namespace vte::grid;
+
+static void
+test_grid_coords (void)
+{
+        /* Default constructor */
+        coords p1;
+
+        /* Construction and assignment */
+
+        coords p2(256,16);
+        g_assert_cmpint(p2.row(), ==, 256);
+        g_assert_cmpint(p2.column(), ==, 16);
+
+        p2.set_row(512);
+        g_assert_cmpint(p2.row(), ==, 512);
+
+        p2.set_column(32);
+        g_assert_cmpint(p2.column(), ==, 32);
+
+        coords p3(256,16);
+        coords p4 = p3;
+        g_assert_cmpint(p3.row(), ==, p4.row());
+        g_assert_cmpint(p3.column(), ==, p4.column());
+
+        /* Comparision operators */
+
+        g_assert_true(p3 == p4);
+        g_assert_false(p3 != p4);
+
+        p4.set_row(32);
+        g_assert_false(p3 == p4);
+        g_assert_true(p3 != p4);
+
+        g_assert_true (coords(42, 21) <= coords(42, 21));
+        g_assert_false(coords(42, 21) >  coords(42, 21));
+        g_assert_false(coords(42, 21) <  coords(42, 21));
+        g_assert_true (coords(42, 21) >= coords(42, 21));
+
+        g_assert_true (coords(42, 42) <= coords(43, 16));
+        g_assert_true (coords(42, 42) <  coords(43, 16));
+        g_assert_false(coords(42, 42) >= coords(43, 16));
+        g_assert_false(coords(42, 42) >  coords(43, 16));
+
+        g_assert_true (coords(42, 42) <= coords(43, 160));
+        g_assert_true (coords(42, 42) <  coords(43, 160));
+        g_assert_false(coords(42, 42) >= coords(43, 160));
+        g_assert_false(coords(42, 42) >  coords(43, 160));
+}
+
+static void
+test_grid_span (void)
+{
+        /* Default constructor */
+        span s1;
+
+        /* Construction and assignment */
+
+        coords s2s(16, 16), s2e(32, 32);
+        span s2(s2s, s2e);
+        g_assert_true(s2.start() == s2s);
+        g_assert_true(s2.end() == s2e);
+        g_assert_cmpint(s2.start_row(), ==, s2s.row());
+        g_assert_cmpint(s2.start_column(), ==, s2s.column());
+        g_assert_cmpint(s2.end_row(), ==, s2e.row());
+        g_assert_cmpint(s2.end_column(), ==, s2e.column());
+
+        span s3 = s2;
+        g_assert_true(s2 == s3);
+        g_assert_false(s2 != s3);
+
+        span s4(16, 16, 32, 32);
+        g_assert_true(s2 == s4);
+        g_assert_false(s2 != s4);
+
+        coords p4s(24, 24);
+        s4.set_start(p4s);
+        g_assert_true(s4.start() == p4s);
+
+        coords p4e(80, 80);
+        s4.set_end(p4e);
+        g_assert_true(s4.end() == p4e);
+
+        /* Empty and operator bool */
+        span s5 = s2;
+        g_assert_true(s5);
+        g_assert_false(s5.empty());
+
+        s5.clear();
+        g_assert_false(s5);
+        g_assert_true(s5.empty());
+
+        s5 = span(coords(32, 32), coords(16, 16));
+        g_assert_false(s5);
+        g_assert_true(s5.empty());
+
+        /* Contains */
+
+        span s6(16, 16, 16, 32);
+        g_assert_false(s6.contains(coords(15, 24)));
+        g_assert_false(s6.contains(coords(16, 15)));
+        g_assert_true (s6.contains(coords(16, 16)));
+        g_assert_true (s6.contains(coords(16, 31)));
+        g_assert_true (s6.contains(coords(16, 32)));
+        g_assert_false(s6.contains(coords(16, 33)));
+        g_assert_false(s6.contains(coords(17, 15)));
+        g_assert_false(s6.contains(coords(17, 16)));
+
+        span s7(16, 16, 32, 8);
+        g_assert_false(s7.contains(coords(15, 4)));
+        g_assert_false(s7.contains(coords(16, 15)));
+        g_assert_true (s7.contains(coords(16, 16)));
+        g_assert_true (s7.contains(coords(16, 42)));
+        g_assert_true (s7.contains(coords(17, 42)));
+        g_assert_true (s7.contains(coords(31, 100)));
+        g_assert_true (s7.contains(coords(32, 8)));
+        g_assert_false(s7.contains(coords(32, 9)));
+        g_assert_false(s7.contains(coords(33, 2)));
+
+        span s8(16, 16, 32, 32);
+        g_assert_false(s8.box_contains(coords(15, 15)));
+        g_assert_false(s8.box_contains(coords(15, 24)));
+        g_assert_false(s8.box_contains(coords(15, 42)));
+        g_assert_false(s8.box_contains(coords(16, 15)));
+        g_assert_true (s8.box_contains(coords(16, 16)));
+        g_assert_true (s8.box_contains(coords(16, 24)));
+        g_assert_true (s8.box_contains(coords(16, 32)));
+        g_assert_false(s8.box_contains(coords(16, 33)));
+        g_assert_false(s8.box_contains(coords(24, 15)));
+        g_assert_true (s8.box_contains(coords(24, 16)));
+        g_assert_true (s8.box_contains(coords(24, 24)));
+        g_assert_true (s8.box_contains(coords(24, 32)));
+        g_assert_false(s8.box_contains(coords(24, 33)));
+        g_assert_false(s8.box_contains(coords(32, 15)));
+        g_assert_true (s8.box_contains(coords(32, 16)));
+        g_assert_true (s8.box_contains(coords(32, 24)));
+        g_assert_true (s8.box_contains(coords(32, 32)));
+        g_assert_false(s8.box_contains(coords(32, 33)));
+        g_assert_false(s8.box_contains(coords(33, 15)));
+        g_assert_false(s8.box_contains(coords(33, 24)));
+        g_assert_false(s8.box_contains(coords(3, 42)));
+}
+
+int
+main(int argc, char *argv[])
+{
+        g_test_init (&argc, &argv, NULL);
+
+        g_test_add_func("/vte/c++/grid/coords", test_grid_coords);
+        g_test_add_func("/vte/c++/grid/span", test_grid_span);
+
+        return g_test_run();
+}
+
+#endif /* MAIN */
diff --git a/src/vtetypes.hh b/src/vtetypes.hh
new file mode 100644
index 0000000..acb8988
--- /dev/null
+++ b/src/vtetypes.hh
@@ -0,0 +1,83 @@
+/*
+ * Copyright © 2015 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+namespace vte {
+namespace grid {
+
+        typedef long vte_int_row_t;
+        typedef long vte_int_column_t;
+
+        struct coords {
+        public:
+                coords() = default;
+                coords(vte_int_row_t r, vte_int_column_t c) : m_row(r), m_column(c) { }
+
+                inline void set_row(vte_int_row_t r)       { m_row = r; }
+                inline void set_column(vte_int_column_t c) { m_column = c; }
+
+                inline vte_int_row_t row()       const { return m_row; }
+                inline vte_int_column_t column() const { return m_column; }
+
+                inline bool operator == (coords const& rhs) const { return m_row == rhs.m_row && m_column == 
rhs.m_column; }
+                inline bool operator != (coords const& rhs) const { return m_row != rhs.m_row || m_column != 
rhs.m_column; }
+
+                inline bool operator <  (coords const& rhs) const { return m_row < rhs.m_row || (m_row == 
rhs.m_row && m_column <  rhs.m_column); }
+                inline bool operator <= (coords const& rhs) const { return m_row < rhs.m_row || (m_row == 
rhs.m_row && m_column <= rhs.m_column); }
+                inline bool operator >  (coords const& rhs) const { return m_row > rhs.m_row || (m_row == 
rhs.m_row && m_column >  rhs.m_column); }
+                inline bool operator >= (coords const& rhs) const { return m_row > rhs.m_row || (m_row == 
rhs.m_row && m_column >= rhs.m_column); }
+
+        private:
+                vte_int_row_t m_row;
+                vte_int_column_t m_column;
+        };
+
+        struct span {
+        public:
+                span() = default;
+                span(coords const& s, coords const& e) : m_start(s), m_end(e) { }
+                span(vte_int_row_t sr, vte_int_column_t sc, vte_int_row_t er, vte_int_column_t ec) : 
m_start(sr, sc), m_end(er, ec) { }
+
+                inline void set_start(coords const& s) { m_start = s; }
+                inline void set_end(coords const& e) { m_end = e; }
+
+                inline bool operator == (span const& rhs) const { return m_start == rhs.m_start && m_end == 
rhs.m_end; }
+                inline bool operator != (span const& rhs) const { return m_start != rhs.m_start || m_end != 
rhs.m_end; }
+
+                inline coords const& start() const { return m_start; }
+                inline coords const& end()   const { return m_end; }
+                inline vte_int_row_t start_row()       const { return m_start.row(); }
+                inline vte_int_row_t end_row()         const { return m_end.row(); }
+                inline vte_int_column_t start_column() const { return m_start.column(); }
+                inline vte_int_column_t end_column()   const { return m_end.column(); }
+
+                inline void clear() { m_start = coords(-1, -1); m_end = coords(-2, -2); }
+                inline bool empty() const { return m_start > m_end; }
+                inline explicit operator bool() const { return !empty(); }
+
+                inline bool contains(coords const& p) const { return m_start <= p && p <= m_end; }
+                inline bool box_contains(coords const& p) const { return m_start.row() <= p.row() && p.row() 
<= m_end.row() &&
+                                                                         m_start.column() <= p.column() && 
p.column() <= m_end.column(); }
+
+        private:
+                coords m_start;
+                coords m_end;
+        };
+
+} /* namespace grid */
+} /* namespace vte */


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