Page MenuHomec4science

cast.hh
No OneTemporary

File Metadata

Created
Mon, May 13, 19:51
/**
* @file
*
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @section LICENSE
*
* Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Tamaas is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Tamaas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Tamaas. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#ifndef __CAST_HH__
#define __CAST_HH__
/* -------------------------------------------------------------------------- */
#include "grid_base.hh"
#include "surface.hh"
#include "numpy.hh"
/* -------------------------------------------------------------------------- */
#include <pybind11/cast.h>
#include <boost/preprocessor/seq.hpp>
/* -------------------------------------------------------------------------- */
namespace pybind11 {
namespace detail {
/**
* Type caster for grid classes
* inspired by https://tinyurl.com/y8m47qh3 from T. De Geus
* and pybind11/eigen.h
*/
template <template <typename, unsigned int> class G, typename T,
unsigned int dim>
struct type_caster<G<T, dim>> {
using type = G<T, dim>;
template <typename U>
using array_type = array_t<U, array::c_style | array::forcecast>;
public:
PYBIND11_TYPE_CASTER(type, _("GridWrap<T, dim>"));
/**
* Conversion part 1 (Python->C++): convert a PyObject into a grid
* instance or return false upon failure. The second argument
* indicates whether implicit conversions should be applied.
*/
bool load(handle src, bool convert) {
if (!convert && !array_type<typename type::value_type>::check_(src))
return false;
auto buf = array_type<typename type::value_type>::ensure(src);
value.move(tamaas::wrap::GridNumpy<G<T, dim>>(buf));
return true;
}
/**
* Conversion part 2 (C++ -> Python): convert a grid instance into
* a Python object. The second and third arguments are used to
* indicate the return value policy and parent object (for
* ``return_value_policy::reference_internal``) and are generally
* ignored by implicit casters.
*
* TODO: do not ignore policy (see pybind11/eigen.h)
*/
static handle cast(const type& src, return_value_policy /* policy */,
handle /*parent*/) {
if (src.getNbComponents() == 1) {
// none() passed as parent to get a correct nocopy
auto a = array_type<T>(src.sizes(), src.getInternalData(), none());
return a.release();
} else {
std::array<unsigned int, dim+1> sizes;
std::copy_n(src.sizes().begin(), dim, sizes.begin());
sizes.back() = src.getNbComponents();
// none() passed as parent to get a correct nocopy
auto a = array_type<T>(sizes, src.getInternalData(), none());
return a.release();
}
}
};
/**
* Type caster for GridBase classes
*/
template <typename T>
struct type_caster<tamaas::GridBase<T>> {
using type = tamaas::GridBase<T>;
template <typename U>
using array_type = array_t<U, array::c_style | array::forcecast>;
public:
PYBIND11_TYPE_CASTER(type, _("GridBaseWrap<T>"));
bool load(handle src, bool convert) {
if (!convert && !array_type<T>::check_(src))
return false;
auto buf = array_type<T>::ensure(src);
value.move(tamaas::wrap::GridBaseNumpy<T>(buf));
return true;
}
static handle cast(const type& src, return_value_policy /* policy */,
handle /*parent*/) {
#define GRID_BASE_CASE(unused1, unused2, dim) \
case dim: { \
const tamaas::Grid<T, dim>& conv = static_cast<decltype(conv)>(src); \
if (src.getNbComponents() != 1) { \
std::array<unsigned int, dim + 1> sizes; \
std::copy_n(conv.sizes().begin(), dim, sizes.begin()); \
sizes.back() = src.getNbComponents(); \
return array_type<T>(sizes, src.getInternalData(), none()).release(); \
} else { \
return array_type<T>(conv.sizes(), src.getInternalData(), none()) \
.release(); \
} \
}
switch (src.getDimension()) {
BOOST_PP_SEQ_FOR_EACH(GRID_BASE_CASE, ~, (1)(2)(3));
default:
return nullptr;
}
#undef GRID_BASE_CASE
}
};
/**
* Type caster for surface class
*/
template <typename T>
struct type_caster<tamaas::Surface<T>> {
using type = tamaas::Surface<T>;
template <typename U>
using array_type = array_t<U, array::c_style | array::forcecast>;
public:
PYBIND11_TYPE_CASTER(type, _("SurfaceWrap<T, dim>"));
bool load(handle src, bool convert) {
if (!convert && !array_type<T>::check_(src))
return false;
auto buf = array_type<T>::ensure(src);
value.move(tamaas::wrap::SurfaceNumpy<type>(buf));
return true;
}
static handle cast(const type& src, return_value_policy /* policy */,
handle /*parent*/) {
auto a = array_type<T>(src.sizes(), src.getInternalData(), none());
return a.release();
}
};
} // namespace detail
} // namespace pybind11
#endif // __CAST_HH__

Event Timeline