00001 // Copyright (C) 2001, 2002, 2003, 2004 EPITA Research and Development Laboratory 00002 // 00003 // This file is part of the Olena Library. This library is free 00004 // software; you can redistribute it and/or modify it under the terms 00005 // of the GNU General Public License version 2 as published by the 00006 // Free Software Foundation. 00007 // 00008 // This library is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 // General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this library; see the file COPYING. If not, write to 00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston, 00016 // MA 02111-1307, USA. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software library without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to 00022 // produce an executable, this file does not by itself cause the 00023 // resulting executable to be covered by the GNU General Public 00024 // License. This exception does not however invalidate any other 00025 // reasons why the executable file might be covered by the GNU General 00026 // Public License. 00027 00028 #ifndef METALIC_OPTIONAL_HH 00029 # define METALIC_OPTIONAL_HH 00030 00031 // FIXME: this code is neither tested or used anywhere. Should stay 00032 // disabled until at least one test is written. -- Nicolas Burrus 00033 00034 # if 0 00035 00036 namespace mlc 00037 { 00038 00039 // This class is used as a static tag for specialization of certain 00040 // algorithm. Usually, it is used to mention that there is nothing 00041 // to do. 00042 struct none {}; 00043 00044 // Option encapsulates a value in a sum type : Some t | None. 00045 template <class T> 00046 struct Option 00047 { 00048 Option(none) : t_(0) {} 00049 Option(T& t) : t_(&t) {} 00050 T* t_; 00051 operator T&() { return *t_; } 00052 }; 00053 00054 // Optional is meant to enable optional static argument with variant 00055 // types. The 'Decl' argument must have a free template argument to 00056 // permit the substitution of the class 'none' to it when no 00057 // argument is given. 00058 // example: 00059 // 00060 // template <class U, class T> 00061 // void foo(U arg1, Optional(T& arg2)) // here T is free. 00062 // {} 00063 // 00064 // Then, you can write: 00065 // foo(1); // T = none 00066 // foo(1, 2); // T = int 00067 // foo(1, "bar"); // T = char * 00068 # define Optional(T, v) ((Option<T > v) = none()) 00069 00070 // Depending on the presence of optional argument, we have different 00071 // specialization of the algorithm. Here are several helper classes 00072 // and macros. 00073 00074 // Do nothing in the general case. 00075 template <class Behaviour, class OptionalArgument> 00076 struct optional_behavior 00077 { 00078 static inline void do_it() 00079 {} 00080 00081 template <class T> 00082 static inline void do_it(T) 00083 {} 00084 00085 template <class T, class U> 00086 static inline void do_it(T, U) 00087 {} 00088 00089 template <class T, class U, class V> 00090 static inline void do_it(T, U, V) 00091 {} 00092 }; 00093 00094 # define DoNothingWhenNone(Behaviour) \ 00095 template <> \ 00096 struct optional_behavior<Behaviour, none> \ 00097 { \ 00098 static inline void do_it() \ 00099 {} \ 00100 \ 00101 template <class T> \ 00102 static inline void do_it(T) \ 00103 {} \ 00104 \ 00105 template <class T, class U> \ 00106 static inline void do_it(T, U) \ 00107 {} \ 00108 \ 00109 template <class T, class U, class V> \ 00110 static inline void do_it(T, U, V) \ 00111 {} \ 00112 }; 00113 00114 00115 } // end of mlc 00116 00117 # endif 00118 00119 #endif // METALIC_OPTIONAL_HH