lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [4946] Begin designing a generic contains() function templ


From: Greg Chicares
Subject: [lmi-commits] [4946] Begin designing a generic contains() function template (VZ and GWC)
Date: Thu, 13 May 2010 01:09:42 +0000

Revision: 4946
          http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=4946
Author:   chicares
Date:     2010-05-13 01:09:42 +0000 (Thu, 13 May 2010)
Log Message:
-----------
Begin designing a generic contains() function template (VZ and GWC)

Modified Paths:
--------------
    lmi/trunk/ChangeLog
    lmi/trunk/Makefile.am
    lmi/trunk/objects.make

Added Paths:
-----------
    lmi/trunk/contains.hpp
    lmi/trunk/contains_test.cpp

Modified: lmi/trunk/ChangeLog
===================================================================
--- lmi/trunk/ChangeLog 2010-05-13 01:08:34 UTC (rev 4945)
+++ lmi/trunk/ChangeLog 2010-05-13 01:09:42 UTC (rev 4946)
@@ -25717,3 +25717,19 @@
   multidimgrid_tools.hpp
 Prevent copying classes with reference data members.
 
+20100513T0108Z <address@hidden> [706]
+
+  config.hpp
+  test_coding_rules.cpp
+Recognize version macros for EDG compilers.
+
+20100513T0109Z <address@hidden> [706]
+
+  Makefile.am
+  contains.hpp      [new file]
+  contains_test.cpp [new file]
+  objects.make
+Begin designing a generic contains() function template (VZ and GWC).
+See:
+  http://lists.nongnu.org/archive/html/lmi/2010-05/msg00008.html
+

Modified: lmi/trunk/Makefile.am
===================================================================
--- lmi/trunk/Makefile.am       2010-05-13 01:08:34 UTC (rev 4945)
+++ lmi/trunk/Makefile.am       2010-05-13 01:09:42 UTC (rev 4946)
@@ -93,8 +93,9 @@
     test_authenticity \
     test_calendar_date \
     test_callback \
+    test_comma_punct \
     test_commutation_functions \
-    test_comma_punct \
+    test_contains \
     test_crc32 \
     test_expression_template_0 \
     test_fenv_lmi \
@@ -517,16 +518,21 @@
   callback_test.cpp
 test_callback_CXXFLAGS = $(AM_CXXFLAGS)
 
+test_comma_punct_SOURCES =  \
+  $(common_test_objects) \
+  comma_punct_test.cpp
+test_comma_punct_CXXFLAGS = $(AM_CXXFLAGS)
+
 test_commutation_functions_SOURCES =    \
   $(common_test_objects) \
   commutation_functions.cpp \
   commutation_functions_test.cpp
 test_commutation_functions_CXXFLAGS = $(AM_CXXFLAGS)
 
-test_comma_punct_SOURCES =  \
+test_contains_SOURCES =    \
   $(common_test_objects) \
-  comma_punct_test.cpp
-test_comma_punct_CXXFLAGS = $(AM_CXXFLAGS)
+  contains_test.cpp
+test_crc32_CXXFLAGS = $(AM_CXXFLAGS)
 
 test_crc32_SOURCES =    \
   $(common_test_objects) \
@@ -884,6 +890,7 @@
     config_como_mingw.hpp \
     config_ming323.hpp \
     configurable_settings.hpp \
+    contains.hpp \
     crc32.hpp \
     custom_io_0.hpp \
     data_directory.hpp \

Added: lmi/trunk/contains.hpp
===================================================================
--- lmi/trunk/contains.hpp                              (rev 0)
+++ lmi/trunk/contains.hpp      2010-05-13 01:09:42 UTC (rev 4946)
@@ -0,0 +1,116 @@
+// Ascertain whether a "container" includes a given element.
+//
+// Copyright (C) 2010 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef contains_hpp
+#define contains_hpp
+
+#include "config.hpp"
+
+#include <algorithm> // std::find()
+
+#if defined __BORLANDC__ || defined __COMO_VERSION__ && __COMO_VERSION__ <= 
4303
+#   define LMI_NO_SFINAE
+#endif // defined __BORLANDC__ || defined __COMO_VERSION__ && __COMO_VERSION__ 
<= 4303
+
+#if !defined LMI_NO_SFINAE
+/// Determine whether a class has a find() member.
+///
+/// See:
+///   http://lists.nongnu.org/archive/html/lmi/2010-05/msg00008.html
+/// I don't know who invented the technique. This implementation
+/// largely follows this pseudonymous posting:
+///   http://www.rsdn.ru/forum/cpp/2720363.aspx
+/// which, however, was foreshadowed here:
+///   http://lists.boost.org/Archives/boost/2002/03/27233.php
+
+template<typename T>
+struct has_member_find
+{
+    typedef char (&yea_t)[1];
+    typedef char (&nay_t)[2];
+
+    struct Mixin {void find();};
+    struct Derived : T, Mixin {};
+
+    template<typename PMF, PMF pmf> struct spoiler;
+
+    template<typename D>
+    static nay_t deduce(D*, spoiler<void (Mixin::*)(), &D::find>* = 0);
+
+    static yea_t deduce(...);
+
+    static bool const value = sizeof(yea_t) == sizeof deduce((Derived*)(0));
+};
+#endif // !defined LMI_NO_SFINAE
+
+/// Ascertain whether a "container" includes a given element.
+///
+/// Here, consider std::basic_string is considered a "container",
+///   http://www.comeaucomputing.com/iso/lwg-active.html#718
+///   "basic_string is not a sequence"
+///  notwithstanding.
+///
+/// This overload is for "containers" that aren't handled specially.
+
+template<typename T>
+bool contains(T const& t, typename T::value_type const& element)
+{
+    return t.end() != std::find(t.begin(), t.end(), element);
+}
+
+/// Ascertain whether a "container" includes a given element.
+///
+/// If T has 'traits_type::char_type', assume it behaves like 
std::basic_string.
+///
+/// This overload is for std::basic_string::find(std::basic_string).
+
+template<typename T>
+bool contains(T const& t, T const& element, typename T::traits_type::char_type 
const* = 0)
+{
+    return T::npos != t.find(element);
+}
+
+/// Ascertain whether a "container" includes a given element.
+///
+/// If T has 'traits_type::char_type', assume it behaves like 
std::basic_string.
+///
+/// This overload is for std::basic_string::find(traits_type::char_type 
const*).
+
+template<typename T>
+bool contains(T const& t, typename T::traits_type::char_type const* element)
+{
+    return T::npos != t.find(element);
+}
+
+/// Ascertain whether a "container" includes a given element.
+///
+/// If T has 'key_type', assume it behaves like an associative container.
+
+template<typename T>
+bool contains(T const& t, typename T::key_type const& element)
+{
+    return t.end() != t.find(element);
+}
+
+#endif // contains_hpp
+


Property changes on: lmi/trunk/contains.hpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/contains_test.cpp
===================================================================
--- lmi/trunk/contains_test.cpp                         (rev 0)
+++ lmi/trunk/contains_test.cpp 2010-05-13 01:09:42 UTC (rev 4946)
@@ -0,0 +1,91 @@
+// Ascertain whether a "container" includes a given element--unit test.
+//
+// Copyright (C) 2010 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+#   include "pchfile.hpp"
+#   pragma hdrstop
+#endif // __BORLANDC__
+
+#include "contains.hpp"
+
+#include "test_tools.hpp"
+
+#include <boost/static_assert.hpp>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+struct HasFind   {void find();};
+struct LacksFind {            };
+
+void test_has_member_find()
+{
+#if !defined LMI_NO_SFINAE
+    BOOST_STATIC_ASSERT( has_member_find<HasFind  >::value);
+    BOOST_STATIC_ASSERT(!has_member_find<LacksFind>::value);
+
+    BOOST_STATIC_ASSERT( has_member_find<std::string>::value);
+
+    BOOST_STATIC_ASSERT(( has_member_find<std::map   <int,int> >::value));
+    BOOST_STATIC_ASSERT ( has_member_find<std::set   <int    > >::value) ;
+    BOOST_STATIC_ASSERT (!has_member_find<std::vector<int    > >::value) ;
+#endif // !defined LMI_NO_SFINAE
+}
+
+void test_contains()
+{
+    std::string const s("etaoin shrdlu");
+    std::string const t("lorem ipsum");
+    BOOST_TEST( contains(s, s));
+    BOOST_TEST(!contains(s, t));
+    BOOST_TEST( contains(s, "eta"));
+    BOOST_TEST(!contains(s, "zeta"));
+
+#if 0 // This is where has_member_find<> will help.
+    std::set<std::string> u;
+    u.insert("one");
+    BOOST_TEST( contains(u, "one"));
+    BOOST_TEST(!contains(u, "two"));
+#endif // 0
+
+    std::map<std::string, int> m;
+    m["one"] = 1;
+    BOOST_TEST( contains(m, "one"));
+    BOOST_TEST(!contains(m, "two"));
+
+    std::vector<double> v;
+    v.push_back(3.14);
+    BOOST_TEST( contains(v, 3.14));
+    BOOST_TEST(!contains(v, 0.00));
+}
+
+int test_main(int, char*[])
+{
+    test_has_member_find();
+    test_contains();
+
+    return 0;
+}
+


Property changes on: lmi/trunk/contains_test.cpp
___________________________________________________________________
Added: svn:keywords
   + Id

Modified: lmi/trunk/objects.make
===================================================================
--- lmi/trunk/objects.make      2010-05-13 01:08:34 UTC (rev 4945)
+++ lmi/trunk/objects.make      2010-05-13 01:09:42 UTC (rev 4946)
@@ -450,6 +450,7 @@
   callback_test \
   comma_punct_test \
   commutation_functions_test \
+  contains_test \
   crc32_test \
   expression_template_0_test \
   fenv_lmi_test \
@@ -579,6 +580,10 @@
   expm1.o \
   timer.o \
 
+contains_test$(EXEEXT): \
+  $(common_test_objects) \
+  contains_test.o \
+
 crc32_test$(EXEEXT): \
   $(common_test_objects) \
   crc32.o \




reply via email to

[Prev in Thread] Current Thread [Next in Thread]