From 5f5af8f4a9c4e7ad1c6df102a666931e3f87f50e Mon Sep 17 00:00:00 2001
From: Markus Blatt <mblatt@dune-project.org>
Date: Wed, 18 May 2005 19:26:33 +0000
Subject: [PATCH] Added template meta programms for calculatation of the
 greatest common divisor and the least common multiple of two longs.

[[Imported from SVN: r2077]]
---
 common/gcd.hh             | 77 +++++++++++++++++++++++++++++++++++++++
 common/lcm.hh             | 40 ++++++++++++++++++++
 common/test/.gitignore    |  3 +-
 common/test/Makefile.am   |  4 +-
 common/test/gcdlcdtest.cc | 25 +++++++++++++
 5 files changed, 147 insertions(+), 2 deletions(-)
 create mode 100644 common/gcd.hh
 create mode 100644 common/lcm.hh
 create mode 100644 common/test/gcdlcdtest.cc

diff --git a/common/gcd.hh b/common/gcd.hh
new file mode 100644
index 000000000..1604b6bc2
--- /dev/null
+++ b/common/gcd.hh
@@ -0,0 +1,77 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_GCD_HH
+#define DUNE_GCD_HH
+
+#include "helpertemplates.hh"
+namespace Dune
+{
+  /**
+   * @addtogroup Common
+   * @{
+   */
+  /**
+   * @file
+   * This file provides template constructs for calculation the
+   * greatest common divisor.
+   */
+
+  /**
+   * @brief Helper for calculating the gcd.
+   */
+  template<long a, long b, bool bo>
+  struct GcdHelper
+  {};
+
+
+  template<long a, long b>
+  struct GcdHelper<a,b,true>
+  {
+    /**
+     * @brief Check that a>b.
+     */
+    static void conceptCheck()
+    {
+      IsTrue<b<a>::yes();
+      IsTrue<0<b>::yes();
+    }
+
+
+    /**
+     * @brief The greatest common divisor of the numbers a and b.
+     */
+    const static long gcd = GcdHelper<b,a%b,true>::gcd;
+  };
+
+  template<long a, long b>
+  struct GcdHelper<a,b,false>
+  {
+    /**
+     * @brief The greatest common divisor of the numbers a and b.
+     */
+    const static long gcd = GcdHelper<b,a,true>::gcd;
+  };
+  template<long a>
+  struct GcdHelper<a,0,true>
+  {
+    const static long gcd=a;
+  };
+
+
+  /**
+   * @brief Calculator of the greatest common divisor.
+   */
+  template<long a, long b>
+  struct Gcd
+  {
+    /**
+     * @brief The greatest common divisior of a and b. */
+    const static long value = GcdHelper<a,b,(a>b)>::gcd;
+  };
+
+  /**
+   * @}
+   */
+}
+
+#endif
diff --git a/common/lcm.hh b/common/lcm.hh
new file mode 100644
index 000000000..6b279db9b
--- /dev/null
+++ b/common/lcm.hh
@@ -0,0 +1,40 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_LCM_HH
+#define DUNE_LCM_HH
+
+#include <dune/common/helpertemplates.hh>
+
+namespace Dune
+{
+
+  /**
+   * @addtogroup Common
+   * @{
+   */
+  /**
+   * @file
+   * This file provides template constructs for calculation the
+   * least common multiple.
+   */
+
+  /**
+   * @brief Calculate the least common multiple of two numbers
+   */
+  template<long m, long n>
+  struct Lcm
+  {
+    static void conceptCheck()
+    {
+      IsTrue<0<m>::yes();
+      IsTrue<0<n>::yes();
+    }
+    /**
+     * @brief The least common multiple of the template parameters
+     * m and n.
+     */
+    const static long value = (m/Gcd<m,n>::value)*n;
+  };
+}
+
+#endif
diff --git a/common/test/.gitignore b/common/test/.gitignore
index 702ff0eff..2f7d246ce 100644
--- a/common/test/.gitignore
+++ b/common/test/.gitignore
@@ -15,4 +15,5 @@ fmatrixtest
 poolallocatortest
 *.gcda
 *.gcno
-gmon.out
\ No newline at end of file
+gmon.out
+gcdlcdtest
\ No newline at end of file
diff --git a/common/test/Makefile.am b/common/test/Makefile.am
index 966a8b049..5d4f76904 100644
--- a/common/test/Makefile.am
+++ b/common/test/Makefile.am
@@ -2,7 +2,7 @@
 
 TESTPROGS = parsetest test-stack arraylisttest smartpointertest \
 	sllisttest iteratorfacadetest tuplestest fmatrixtest \
-	poolallocatortest settest
+	poolallocatortest settest gcdlcdtest
 
 # which tests to run
 TESTS = $(TESTPROGS)
@@ -37,4 +37,6 @@ poolallocatortest_SOURCES = poolallocatortest.cc
 
 settest_SOURCES=settest.cc
 
+gcdlcdtest_SOURCES = gcdlcdtest.cc
+
 include $(top_srcdir)/am/sourcescheck
diff --git a/common/test/gcdlcdtest.cc b/common/test/gcdlcdtest.cc
new file mode 100644
index 000000000..3513e7b52
--- /dev/null
+++ b/common/test/gcdlcdtest.cc
@@ -0,0 +1,25 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#include <dune/common/gcd.hh>
+#include <dune/common/lcm.hh>
+#include <dune/common/helpertemplates.hh>
+#include <iostream>
+
+void test()
+{
+  IsTrue<(Dune::Gcd<2*2*2*5*5*5*11, 2*2*5*13>::value == 2*2*5)>::yes();
+  IsTrue<Dune::Lcm<11,3>::value == 33>::yes();
+  IsTrue<Dune::Lcm<18,15>::value == 18*15/3>::yes();
+  IsTrue<Dune::Lcm<10800,Dune::Lcm<36000,7680>::value>::value==1728000>::yes();
+}
+
+int main()
+{
+  std::cout<<" gcd(2,5)="<<Dune::Gcd<2,5>::value<<" gcd(3, 18)="
+           <<Dune::Gcd<3,18>::value<<" gcd("<<2*2*2*5*5*5*11<<", "
+           << 2*2*5*13<<")="<<Dune::Gcd<2*2*2*5*5*5*11, 2*2*5*13>::value
+           <<std::endl;
+  std::cout<<" lcm(18,15)="<<Dune::Lcm<18,15>::value
+           <<" lcm(10800,36000,7680)="<<Dune::Lcm<10800,Dune::Lcm<36000,7680>::value>::value<<std::endl;
+
+}
-- 
GitLab