VectorInterface.h

00001 /*
00002  * This source file is part of libRocket, the HTML/CSS Interface Middleware
00003  *
00004  * For the latest information, see http://www.librocket.com
00005  *
00006  * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a copy
00009  * of this software and associated documentation files (the "Software"), to deal
00010  * in the Software without restriction, including without limitation the rights
00011  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00012  * copies of the Software, and to permit persons to whom the Software is
00013  * furnished to do so, subject to the following conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be included in
00016  * all copies or substantial portions of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00021  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00022  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00023  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00024  * THE SOFTWARE.
00025  *
00026  */
00027 
00028 #ifndef ROCKETCOREPYTHONVECTORINTERFACE_H
00029 #define ROCKETCOREPYTHONVECTORINTERFACE_H
00030 
00031 namespace Rocket {
00032 namespace Core {
00033 namespace Python {
00034 
00046 template <typename Container>
00047 class VectorInterface
00048 {
00049 public:
00050         VectorInterface(const char* name)
00051         {
00052                 python::class_< Container >(name)
00053                         .def("__len__", &VectorInterface< Container >::Size)
00054                         .def("__setitem__", &VectorInterface< Container >::SetItem)
00055                         .def("__delitem__", &VectorInterface< Container >::DelItem)
00056                         .def("__getitem__", &VectorInterface< Container >::GetItem, python::return_value_policy< python::return_by_value >())
00057                         .def("__contains__", &VectorInterface< Container >::Contains)                   
00058                 ;
00059         }
00060 
00061         static size_t Size(const Container& container)
00062         {
00063                 return container.size();
00064         }
00065 
00066         static void SetItem(Container& container, int index, const typename Container::value_type& value)
00067         {
00068                 if (index < 0)
00069                         index = container.size() + index;
00070                 if (index >= (int)container.size())
00071                         container.resize(index + 1);
00072 
00073                 container[index] = value;
00074         }
00075 
00076         static void DelItem(Container& container, int index)
00077         {
00078                 if (index >= (int)container.size())
00079                 {
00080                         PyErr_SetString(PyExc_IndexError, String(32, "Invalid index %d", index).CString());
00081                         python::throw_error_already_set();
00082                 }
00083 
00084                 container.erase(container.begin() + index);
00085         }
00086 
00087         static typename Container::value_type& GetItem(Container& container, int index)
00088         {
00089                 if (index < 0)
00090                         index = container.size() + index;
00091 
00092                 if (index >= (int)container.size())
00093                 {
00094                         PyErr_SetString(PyExc_IndexError, String(32, "Invalid index %d", index).CString());
00095                         python::throw_error_already_set();
00096                 }
00097 
00098                 return container[index];
00099         }
00100 
00101         static bool Contains(Container& container, const typename Container::value_type& value)
00102         {
00103                 for (typename Container::iterator itr = container.begin(); itr != container.end(); ++itr)
00104                 {
00105                         if ((*itr) == value)
00106                                 return true;
00107                 }
00108 
00109                 return false;
00110         }
00111 };
00112 
00113 }
00114 }
00115 }
00116 
00117 #endif
00118