00001 // Copyright (C) 2001, 2002, 2003 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 NTG_CORE_INTERVAL_HH 00029 # define NTG_CORE_INTERVAL_HH 00030 00031 # include <ntg/config/system.hh> 00032 # include <ntg/core/macros.hh> 00033 # include <ntg/core/type_traits.hh> 00034 00035 # include <string> 00036 # include <sstream> 00037 00038 /* 00039 Classes to define intervals. The problem with static intervals is 00040 that you cannot specify it easily: 00041 00042 template <T lower, T upper> 00043 struct foo {} 00044 00045 What do you specify for T ? If you use unsigned, you cannot handle 00046 negative values, if you use signed, you won't be able to use the max 00047 of an unsigned. That's why you have to specify the type of the 00048 bounds. Interval is an handy way to do this. 00049 00050 Note: it is not possible to define float intervals, as floats cannot 00051 be template parameters. 00052 */ 00053 00054 namespace ntg 00055 { 00056 00057 /*-------------------------. 00058 | bounded<T, i_min, i_max> | 00059 `-------------------------*/ 00060 00061 template <class T, T i_min, T i_max> 00062 class bounded 00063 { 00064 public: 00065 typedef T storage_type; 00066 00067 static T min() { return i_min; } 00068 static T max() { return i_max; } 00069 static T inf() { return i_min; } 00070 static T sup() { return i_max; } 00071 00072 static std::string 00073 name() 00074 { 00075 std::ostringstream out; 00076 out << "bounded<" << ntg_name(T) << ", " << i_min 00077 << ", " << i_max << ">"<< std::ends; 00078 return out.str(); 00079 } 00080 }; 00081 00082 /*------------------------. 00083 | bounded_u<i_min, i_max> | 00084 `------------------------*/ 00085 00086 template <unsigned i_min, unsigned i_max> 00087 class bounded_u : public bounded<unsigned, i_min, i_max> 00088 { 00089 public: 00090 static std::string 00091 name() 00092 { 00093 std::ostringstream out; 00094 out << "bounded_u<" << i_min << ", " << i_max << ">"<< std::ends; 00095 return out.str(); 00096 } 00097 }; 00098 00099 /*------------------------. 00100 | bounded_s<i_min, i_max> | 00101 `------------------------*/ 00102 00103 template <signed i_min, signed i_max> 00104 class bounded_s : public bounded<signed, i_min, i_max> 00105 { 00106 public: 00107 static std::string 00108 name() 00109 { 00110 std::ostringstream out; 00111 out << "bounded_s<" << i_min << ", " << i_max << ">"<< std::ends; 00112 return out.str(); 00113 } 00114 }; 00115 00116 } // end of ntg. 00117 00118 #endif // !NTG_CORE_INTERVAL_HH