File: extensions.h

package info (click to toggle)
dune-common 2.10.0-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,824 kB
  • sloc: cpp: 52,256; python: 3,979; sh: 1,658; makefile: 17
file content (75 lines) | stat: -rw-r--r-- 2,130 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*
    pybind11/extensions.h: Extensions to the C++11 python binding
    generator library for dune-fempy

    Copyright (c) 2016 Andreas Dedner <a.s.dedner@warwick.ac.uk>
    Copyright (c) 2016 Martin Nolte <nolte@mathematik.uni-freiburg.de>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#pragma once

#include <stdexcept>
#include <type_traits>
#include <utility>

#include "pybind11.h"
#include "numpy.h"

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

template <class T>
inline bool already_registered() {
  return static_cast<bool>(detail::get_type_info(typeid(T)));
}


template <class F>
inline void handle_buffer_format(const pybind11::buffer_info &info, F &&f) {
  if(info.format.size() > 2)
    throw std::runtime_error("Buffer format '" + info.format + "' not supported.");
  char format = info.format[0];
  if(format == '=' || format == '<')
    format = info.format[1];
  switch(format) {
  case 'h':
    return f(format_descriptor<short>());
  case 'H':
    return f(format_descriptor<unsigned short>());
  case 'i':
    return f(format_descriptor<int>());
  case 'I':
    return f(format_descriptor<unsigned int>());
  case 'l':
    return f(format_descriptor<long>());
  case 'L':
    return f(format_descriptor<unsigned long>());
  case 'q':
    return f(format_descriptor<long long>());
  case 'Q':
    return f(format_descriptor<unsigned long long>());
  case 'f':
    return f(format_descriptor<float>());
  case 'd':
    return f(format_descriptor<double>());
  default:
    throw std::runtime_error("Buffer format '" + info.format + "' not supported.");
  }
}

template <class T>
inline void implicitly_convert_facades() {
  auto implicit_caster = [](PyObject *obj, PyTypeObject *type) -> PyObject * {
    return getattr(obj, "__impl__", nullptr).release().ptr();
  };

  if(auto tinfo = detail::get_type_info(typeid(T)))
    tinfo->implicit_conversions.push_back(implicit_caster);
  else
    pybind11_fail("impplicitly_convert_facades: Unable to find type " + type_id<T>());
}


PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)