RDCode: PySequenceHolder.h Source File

# 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