00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 00002 /* 00003 * This file is part of the libetonyek project. 00004 * 00005 * This Source Code Form is subject to the terms of the Mozilla Public 00006 * License, v. 2.0. If a copy of the MPL was not distributed with this 00007 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 00008 */ 00009 00010 #ifndef IWORKPROPERTYMAP_H_INCLUDED 00011 #define IWORKPROPERTYMAP_H_INCLUDED 00012 00013 #include <boost/any.hpp> 00014 #include <boost/unordered_map.hpp> 00015 00016 #include "IWORKPropertyInfo.h" 00017 00018 namespace libetonyek 00019 { 00020 00023 class IWORKPropertyMap 00024 { 00025 public: 00026 class NotFoundException {}; 00027 00028 private: 00029 typedef boost::unordered_map<IWORKPropertyID_t, boost::any> Map_t; 00030 00031 public: 00034 IWORKPropertyMap(); 00035 00040 explicit IWORKPropertyMap(const IWORKPropertyMap *parent); 00041 00046 IWORKPropertyMap(const IWORKPropertyMap &other); 00047 00053 IWORKPropertyMap &operator=(const IWORKPropertyMap &other); 00054 00059 void swap(IWORKPropertyMap &other); 00060 00065 void setParent(const IWORKPropertyMap *parent); 00066 00076 template<class Property> 00077 bool has(bool lookInParent = false) const 00078 { 00079 const Map_t::const_iterator it = m_map.find(IWORKPropertyInfo<Property>::id); 00080 if (m_map.end() != it) 00081 return !it->second.empty(); 00082 00083 if (lookInParent && m_parent) 00084 return m_parent->has<Property>(lookInParent); 00085 00086 return false; 00087 } 00088 00089 template<class Property> 00090 bool clears(bool lookInParent = false) const 00091 { 00092 const Map_t::const_iterator it = m_map.find(IWORKPropertyInfo<Property>::id); 00093 if (m_map.end() != it) 00094 return it->second.empty(); 00095 00096 if (lookInParent && m_parent) 00097 return m_parent->clears<Property>(lookInParent); 00098 00099 return false; 00100 } 00101 00111 template<class Property> 00112 const typename IWORKPropertyInfo<Property>::ValueType &get(bool lookInParent = false) const 00113 { 00114 const Map_t::const_iterator it = m_map.find(IWORKPropertyInfo<Property>::id); 00115 if (m_map.end() != it) 00116 { 00117 if (!it->second.empty()) 00118 return boost::any_cast<const typename IWORKPropertyInfo<Property>::ValueType &>(it->second); 00119 } 00120 else if (lookInParent && m_parent) 00121 { 00122 return m_parent->get<Property>(lookInParent); 00123 } 00124 00125 throw NotFoundException(); 00126 } 00127 00132 template<class Property> 00133 void put(const typename IWORKPropertyInfo<Property>::ValueType &value) 00134 { 00135 m_map[IWORKPropertyInfo<Property>::id] = value; 00136 } 00137 00143 template<class Property> 00144 void clear() 00145 { 00146 m_map[IWORKPropertyInfo<Property>::id] = boost::any(); 00147 } 00148 00149 private: 00150 Map_t m_map; 00151 const IWORKPropertyMap *m_parent; 00152 }; 00153 00154 } 00155 00156 #endif // IWORKPROPERTYMAP_H_INCLUDED 00157 00158 /* vim:set shiftwidth=2 softtabstop=2 expandtab: */