Added example for mystring class [Sheplyakov].
authorJens Vollinga <vollinga@thep.physik.uni-mainz.de>
Wed, 5 Sep 2007 16:52:25 +0000 (16:52 +0000)
committerJens Vollinga <vollinga@thep.physik.uni-mainz.de>
Wed, 5 Sep 2007 16:52:25 +0000 (16:52 +0000)
doc/examples/Makefile.am
doc/examples/mystring.cpp [new file with mode: 0644]
doc/tutorial/ginac.texi

index 5ee2c5d347a145be22e0d6d3c83051d69b3951eb..e63da35b5507eb9aea049df6a1685bd0388d6b40 100644 (file)
@@ -1,6 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 
-EXFILES = archive1.cpp compile1.cpp compile2.cpp compile3.cpp lanczos.cpp
+EXFILES = archive1.cpp compile1.cpp compile2.cpp compile3.cpp lanczos.cpp \
+ mystring.cpp
 
 TEXI = ginac-examples.texi
 
diff --git a/doc/examples/mystring.cpp b/doc/examples/mystring.cpp
new file mode 100644 (file)
index 0000000..e9d1259
--- /dev/null
@@ -0,0 +1,103 @@
+/**
+ * @file mystring.cpp Example of extending GiNaC: writing new classes
+ */
+#include <iostream>
+#include <string>   
+#include <stdexcept>
+using namespace std;
+
+#include <ginac/ginac.h>
+using namespace GiNaC;
+
+class mystring : public basic
+{
+       GINAC_DECLARE_REGISTERED_CLASS(mystring, basic)
+public:
+       mystring(const string &s);
+       mystring(const char *s);
+       ex eval(int level) const;
+
+private:
+       string str;
+
+protected:
+       void do_print(const print_context &c, unsigned level = 0) const;
+
+};
+
+GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(mystring, basic,
+  print_func<print_context>(&mystring::do_print))
+
+// ctors
+mystring::mystring() : inherited(&mystring::tinfo_static) { }
+mystring::mystring(const string &s) : inherited(&mystring::tinfo_static), str(s) { }
+mystring::mystring(const char *s) : inherited(&mystring::tinfo_static), str(s) { }
+
+// comparison
+int mystring::compare_same_type(const basic &other) const
+{
+       const mystring &o = static_cast<const mystring &>(other);
+       int cmpval = str.compare(o.str);
+       if (cmpval == 0)
+               return 0;
+       else if (cmpval < 0)
+               return -1;
+       else
+               return 1;
+}
+
+// archiving/unarchiving
+mystring::mystring(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst)
+{
+       n.find_string("string", str);
+}
+
+void mystring::archive(archive_node &n) const
+{
+       inherited::archive(n);
+       n.add_string("string", str);
+}
+
+ex mystring::unarchive(const archive_node &n, lst &sym_lst)
+{
+       return (new mystring(n, sym_lst))->setflag(status_flags::dynallocated);
+}
+
+// printing
+void mystring::do_print(const print_context &c, unsigned level) const
+{
+       // print_context::s is a reference to an ostream
+       c.s << '\"' << str << '\"';
+}
+
+/**
+ * evaluation: all strings automatically converted to lowercase with
+ * non-alphabetic characters stripped, and empty strings removed
+ */
+ex mystring::eval(int level) const
+{
+       string new_str;
+       for (size_t i=0; i<str.length(); i++) {
+               char c = str[i];
+               if (c >= 'A' && c <= 'Z') 
+                       new_str += tolower(c);
+               else if (c >= 'a' && c <= 'z')
+                       new_str += c;
+       }
+
+       if (new_str.length() == 0)
+               return 0;
+       else
+               return mystring(new_str).hold();
+}
+
+int main(int argc, char** argv)
+{
+       ex e = mystring("Hello, world!");
+       cout << is_a<mystring>(e) << endl;
+       cout << ex_to<basic>(e).class_name() << endl;
+       cout << e << endl;
+       ex another = pow(mystring("One string"), 2*sin(Pi-mystring("Another string")));
+       cout << another << endl;
+       return 0;
+}
index a6befadbcb84506e72c7ac5b0ef83efafb47e549..b2038db5bd68e2cd06d359eb6466665e38498ed4 100644 (file)
@@ -7823,7 +7823,8 @@ Now we will start implementing a new class @code{mystring} that allows
 placing character strings in algebraic expressions (this is not very useful,
 but it's just an example). This class will be a direct subclass of
 @code{basic}. You can use this sample implementation as a starting point
-for your own classes.
+for your own classes @footnote{The self-contained source for this example is
+included in GiNaC, see the @file{doc/examples/mystring.cpp} file.}.
 
 The code snippets given here assume that you have included some header files
 as follows: