IWORKPropertyMap.h
Go to the documentation of this file.
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: */