PySequenceHolder.h

Go to the documentation of this file.
00001 //
00002 // Copyright (c) 2003-2006 greg Landrum and Rational Discovery LLC
00003 //
00004 //   @@ All Rights Reserved  @@
00005 //
00006 
00007 #ifndef _RD_PYSEQUENCEHOLDER_H_
00008 #define _RD_PYSEQUENCEHOLDER_H_
00009 
00010 //
00011 // Defines a class to hold sequences passed in from Python
00012 //
00013 #include "Wrap.h"
00014 #include <RDGeneral/Invariant.h>
00015 
00016 namespace python = boost::python;
00017 
00018 //! \brief Class to hold sequences (lists, tuples, arrays, etc.)
00019 //!         passed from Python -> C++
00020 //!
00021 //!  PySequenceHolder is templated on the type of the contained object.
00022 //!
00023 //!  The class is \em lazy: elements are not evaluated until requested
00024 //!     within the C++ code.
00025 //!
00026 template <typename T>
00027 class PySequenceHolder {
00028 public:
00029   PySequenceHolder(python::object seq) {
00030     d_seq = seq;
00031   };
00032 
00033   // --------------------------------------------------
00034   //! \brief Returns the size of the contained sequence.
00035   //!
00036   //! NOTE: the sequence must have a \c __len__ attribute, otherwise
00037   //!       a \c ValueError will be raised.
00038   unsigned int size() const {
00039     unsigned int res=0;
00040     try {
00041       res = python::extract<int>(d_seq.attr("__len__")());
00042     } catch (...) {
00043       throw_value_error("sequence does not support length query");
00044     }
00045     return res;
00046   };
00047 
00048   // --------------------------------------------------
00049   //! \brief Returns an element of the sequence
00050   //!
00051   //! ARGUMENTS:
00052   //!   - which: an integer specifying which element should be returned. 
00053   //!  
00054   //! NOTES:
00055   //!   - if the sequence is not \a which elements long, we raise an
00056   //!     \c IndexError
00057   //!   - if the element cannot be converted to type \c T, we raise a
00058   //!     \c ValueError
00059   T operator[](unsigned int which) const {
00060     if(which > size() || which < 0){
00061       throw_index_error(which);
00062     }
00063 
00064     try{
00065       T res = python::extract<T>(d_seq[which]);
00066       return res;
00067     } catch (...) {
00068       throw_value_error("cannot extract desired type from sequence");
00069     }
00070 
00071     POSTCONDITION(0,"cannot reach this point");
00072     return static_cast<T>(0);
00073   };
00074 private:
00075   python::object d_seq;
00076 };
00077 
00078 
00079 #endif

Generated on Fri Apr 3 06:03:02 2009 for RDCode by  doxygen 1.5.6