00001 /* 00002 libwt - Vassilis Virvilis Toolkit - a widget library 00003 Copyright (C) 2006 Vassilis Virvilis <vasvir2@fastmail.fm> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the 00017 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, SA. 00019 */ 00020 00021 #ifndef WT_ENUM_H 00022 #define WT_ENUM_H 00023 00024 #include <map> 00025 #include <vector> 00026 #include <algorithm> 00027 #include <exception> 00028 #include <cassert> 00029 00030 namespace Wt { 00031 00032 /// typesafe enumaration like class 00033 /*! 00034 Usage example 00035 class ColorEnum : public Enum<ColorEnum> { 00036 public: 00037 static const Member Red; 00038 static const Member Green; 00039 static const Member Purple; 00040 static const Member Black; 00041 }; 00042 00043 // Initialization 00044 ColorEnum::Member Red = 2; 00045 ColorEnum::Member Green; // implied 3 00046 ColorEnum::Member Purple = 47; // forced 47 00047 ColorEnum::Member Black; // implied 48 00048 00049 Now 00050 ColorEnum::Var some_color = Red; //ok; 00051 some_color = 3 //ok 00052 some_color = 9999 //failed at runtime: assertion && exception 00053 */ 00054 template<typename CHILD> 00055 class Enum { 00056 private: 00057 static int enum_next; 00058 static std::vector<int> defined; 00059 00060 class VarBase { 00061 public: 00062 VarBase(int val) 00063 : value(val) {} 00064 operator int() const { 00065 /// \bug GCC bug: requires a (void) 00066 (void) defined; 00067 return value; 00068 } 00069 private: 00070 friend class Enum<CHILD>::Var; 00071 int value; 00072 }; 00073 00074 protected: 00075 class Member : public VarBase { 00076 private: 00077 void store(int val) { 00078 std::vector<int> result(defined.size() + 1); 00079 std::vector<int> newer(1); 00080 newer[0] = val; 00081 std::merge(defined.begin(), defined.end(), 00082 newer.begin(), newer.end(), result.begin()); 00083 std::swap(defined, result); 00084 enum_next = val + 1; 00085 } 00086 public: 00087 Member() 00088 : VarBase(enum_next) { 00089 store(enum_next); 00090 } 00091 Member(int val) 00092 : VarBase(val) { 00093 store(val); 00094 } 00095 }; 00096 00097 public: 00098 class Var : public VarBase { 00099 public: 00100 Var(int val = 0) : VarBase(val) { 00101 *this = val; 00102 } 00103 Var& operator=(int val) { 00104 bool value_is_valid_enum = std::binary_search(defined.begin(), 00105 defined.end(), val); 00106 if (value_is_valid_enum) { 00107 VarBase::value = val; 00108 } else { 00109 assert(value_is_valid_enum); 00110 throw val; 00111 } 00112 return *this; 00113 } 00114 private: 00115 }; 00116 }; 00117 00118 template<typename CHILD> 00119 int Enum<CHILD>::enum_next = 0; 00120 00121 template<typename CHILD> 00122 std::vector<int> Enum<CHILD>::defined; 00123 00124 } // namespace 00125 00126 #endif //WT_ENUM_H 00127
This document is licensed under the terms of the GNU Free Documentation License and may be freely distributed under the conditions given by this license.