1 
2 /******************************************************************************
3 * MODULE     : blackbox.hpp
4 * DESCRIPTION: For hiding the implementation of a type
5 * COPYRIGHT  : (C) 2005  Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11 
12 #ifndef BLACKBOX_H
13 #define BLACKBOX_H
14 #include "basic.hpp"
15 
16 class blackbox_rep: public abstract_struct {
17 public:
blackbox_rep()18   inline blackbox_rep () {}
~blackbox_rep()19   inline virtual ~blackbox_rep () {}
20   virtual int get_type () = 0;
21   virtual bool equal (blackbox_rep* ptr) = 0;
22   virtual tm_ostream& display (tm_ostream& out) = 0;
23 };
24 
25 class blackbox {
26 public:
27 ABSTRACT_NULL(blackbox);
28 };
29 ABSTRACT_NULL_CODE(blackbox);
30 
31 template<class T>
32 class whitebox_rep: public blackbox_rep {
33 public:
34   T data;
35 public:
whitebox_rep(const T & data2)36   inline whitebox_rep (const T& data2): data (data2) {}
~whitebox_rep()37   inline ~whitebox_rep () {}
get_type()38   inline int get_type () { return type_helper<T>::id; }
equal(blackbox_rep * ptr)39   inline bool equal (blackbox_rep* ptr) {
40     return ptr != NULL && ptr->get_type () == type_helper<T>::id &&
41            ((whitebox_rep<T>*) ptr)->data == data; }
display(tm_ostream & out)42   inline tm_ostream& display (tm_ostream& out) { return out << data; }
43 };
44 
operator ==(blackbox bb1,blackbox bb2)45 inline bool operator == (blackbox bb1, blackbox bb2) {
46   if (is_nil (bb1)) return is_nil (bb2);
47   else return bb1->equal (bb2.rep); }
operator !=(blackbox bb1,blackbox bb2)48 inline bool operator != (blackbox bb1, blackbox bb2) {
49   if (is_nil (bb1)) return !is_nil (bb2);
50   else return !bb1->equal (bb2.rep); }
operator <<(tm_ostream & out,blackbox bb)51 inline tm_ostream& operator << (tm_ostream& out, blackbox bb) {
52   if (is_nil (bb)) return out << "nil";
53   else return bb->display (out); }
54 
55 inline int
type_box(blackbox bb)56 type_box (blackbox bb) {
57   return is_nil (bb)? 0: bb->get_type ();
58 }
59 
60 template<class T> blackbox
close_box(const T & data)61 close_box (const T& data) {
62   return tm_new<whitebox_rep<T> > (data);
63 }
64 
65 template<class T> T
open_box(blackbox bb)66 open_box (blackbox bb) {
67   ASSERT (type_box (bb) == type_helper<T>::id, "type mismatch");
68   return ((whitebox_rep<T>*) bb.rep) -> data;
69 }
70 
71 #endif // BLACKBOX_H
72