Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
eae7744c
Commit
eae7744c
authored
May 07, 2016
by
Sergey Lyskov
Committed by
Wenzel Jakob
May 15, 2016
Browse files
adding stl_binders
parent
178c8a89
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
240 additions
and
0 deletions
+240
-0
CMakeLists.txt
CMakeLists.txt
+1
-0
example/example.cpp
example/example.cpp
+2
-0
example/example17.cpp
example/example17.cpp
+27
-0
example/example17.py
example/example17.py
+21
-0
example/example17.ref
example/example17.ref
+5
-0
include/pybind11/stl_binders.h
include/pybind11/stl_binders.h
+184
-0
No files found.
CMakeLists.txt
View file @
eae7744c
...
@@ -128,6 +128,7 @@ set(PYBIND11_EXAMPLES
...
@@ -128,6 +128,7 @@ set(PYBIND11_EXAMPLES
example/example14.cpp
example/example14.cpp
example/example15.cpp
example/example15.cpp
example/example16.cpp
example/example16.cpp
example/example17.cpp
example/issues.cpp
example/issues.cpp
)
)
...
...
example/example.cpp
View file @
eae7744c
...
@@ -25,6 +25,7 @@ void init_ex13(py::module &);
...
@@ -25,6 +25,7 @@ void init_ex13(py::module &);
void
init_ex14
(
py
::
module
&
);
void
init_ex14
(
py
::
module
&
);
void
init_ex15
(
py
::
module
&
);
void
init_ex15
(
py
::
module
&
);
void
init_ex16
(
py
::
module
&
);
void
init_ex16
(
py
::
module
&
);
void
init_ex17
(
py
::
module
&
);
void
init_issues
(
py
::
module
&
);
void
init_issues
(
py
::
module
&
);
#if defined(PYBIND11_TEST_EIGEN)
#if defined(PYBIND11_TEST_EIGEN)
...
@@ -50,6 +51,7 @@ PYBIND11_PLUGIN(example) {
...
@@ -50,6 +51,7 @@ PYBIND11_PLUGIN(example) {
init_ex14
(
m
);
init_ex14
(
m
);
init_ex15
(
m
);
init_ex15
(
m
);
init_ex16
(
m
);
init_ex16
(
m
);
init_ex17
(
m
);
init_issues
(
m
);
init_issues
(
m
);
#if defined(PYBIND11_TEST_EIGEN)
#if defined(PYBIND11_TEST_EIGEN)
...
...
example/example17.cpp
0 → 100644
View file @
eae7744c
/*
example/example17.cpp -- Usade of stl_binders functions
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#include "example.h"
#include <pybind11/stl_binders.h>
class
A
{
public:
A
()
=
delete
;
};
void
init_ex17
(
py
::
module
&
m
)
{
pybind11
::
class_
<
A
>
(
m
,
"A"
);
py
::
vector_binder
<
int
>
(
m
,
"VectorInt"
);
py
::
vector_binder
<
A
>
(
m
,
"VectorA"
);
}
example/example17.py
0 → 100644
View file @
eae7744c
#!/usr/bin/env python
from
__future__
import
print_function
from
example
import
VectorInt
,
VectorA
v_int
=
VectorInt
(
2
)
print
(
v_int
.
size
()
)
print
(
bool
(
v_int
)
)
v_int2
=
VectorInt
(
2
)
print
(
v_int
==
v_int2
)
v_int2
[
1
]
=
1
print
(
v_int
!=
v_int2
)
v_int2
.
push_back
(
2
)
v_int2
.
push_back
(
3
)
print
(
v_int2
)
v_a
=
VectorA
()
example/example17.ref
0 → 100644
View file @
eae7744c
2
True
True
True
VectorInt[0, 1, 2, 3]
include/pybind11/stl_binders.h
0 → 100644
View file @
eae7744c
/*
pybind11/std_binders.h: Convenience wrapper functions for STL containers with C++ like interface
Copyright (c) 2016 Sergey Lyskov
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#ifndef _INCLUDED_std_binders_h_
#define _INCLUDED_std_binders_h_
#include "common.h"
#include "operators.h"
#include <type_traits>
#include <utility>
#include <algorithm>
#include <sstream>
NAMESPACE_BEGIN
(
pybind11
)
template
<
typename
T
>
constexpr
auto
has_equal_operator
(
int
)
->
decltype
(
std
::
declval
<
T
>
()
==
std
::
declval
<
T
>
(),
bool
())
{
return
true
;
}
template
<
typename
T
>
constexpr
bool
has_equal_operator
(...)
{
return
false
;
}
template
<
typename
T
>
constexpr
auto
has_not_equal_operator
(
int
)
->
decltype
(
std
::
declval
<
T
>
()
!=
std
::
declval
<
T
>
(),
bool
())
{
return
true
;
}
template
<
typename
T
>
constexpr
bool
has_not_equal_operator
(...)
{
return
false
;
}
namespace
has_insertion_operator_implementation
{
enum
class
False
{};
struct
any_type
{
template
<
typename
T
>
any_type
(
T
const
&
);
};
False
operator
<<
(
std
::
ostream
const
&
,
any_type
const
&
);
}
template
<
typename
T
>
constexpr
bool
has_insertion_operator
()
{
using
namespace
has_insertion_operator_implementation
;
return
std
::
is_same
<
decltype
(
std
::
declval
<
std
::
ostringstream
&>
()
<<
std
::
declval
<
T
>
()
),
std
::
ostream
&
>::
value
;
}
template
<
typename
T
,
typename
Allocator
=
std
::
allocator
<
T
>,
typename
holder_type
=
std
::
unique_ptr
<
std
::
vector
<
T
,
Allocator
>
>
>
class
vector_binder
{
using
Vector
=
std
::
vector
<
T
,
Allocator
>
;
using
SizeType
=
typename
Vector
::
size_type
;
using
Class_
=
pybind11
::
class_
<
Vector
,
holder_type
>
;
// template<typename U = T, typename std::enable_if< std::is_constructible<U>{} >::type * = nullptr>
// void maybe_constructible(Class_ &cl) {
// cl.def(pybind11::init<>());
// }
// template<typename U = T, typename std::enable_if< !std::is_constructible<U>{} >::type * = nullptr>
// void maybe_constructible(Class_ &cl) {}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
std
::
is_default_constructible
<
U
>{}
>::
type
*
=
nullptr
>
void
maybe_default_constructible
(
Class_
&
cl
)
{
cl
.
def
(
pybind11
::
init
<
SizeType
>
());
cl
.
def
(
"resize"
,
(
void
(
Vector
::*
)(
SizeType
count
))
&
Vector
::
resize
,
"changes the number of elements stored"
);
}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
!
std
::
is_default_constructible
<
U
>{}
>::
type
*
=
nullptr
>
void
maybe_default_constructible
(
Class_
&
)
{}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
std
::
is_copy_constructible
<
U
>{}
>::
type
*
=
nullptr
>
void
maybe_copy_constructible
(
Class_
&
cl
)
{
cl
.
def
(
pybind11
::
init
<
Vector
const
&>
());
}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
!
std
::
is_copy_constructible
<
U
>{}
>::
type
*
=
nullptr
>
void
vector_bind_maybe_copy_constructible
(
Class_
&
)
{}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
has_equal_operator
<
U
>(
0
)
>::
type
*
=
nullptr
>
void
maybe_has_equal_operator
(
Class_
&
cl
)
{
cl
.
def
(
pybind11
::
self
==
pybind11
::
self
);
cl
.
def
(
pybind11
::
self
!=
pybind11
::
self
);
cl
.
def
(
"count"
,
[](
Vector
const
&
v
,
T
const
&
value
)
{
return
std
::
count
(
v
.
begin
(),
v
.
end
(),
value
);
},
"counts the elements that are equal to value"
);
}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
!
has_equal_operator
<
U
>(
0
)
>::
type
*
=
nullptr
>
void
maybe_has_equal_operator
(
Class_
&
)
{}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
has_not_equal_operator
<
U
>(
0
)
>::
type
*
=
nullptr
>
void
maybe_has_not_equal_operator
(
Class_
&
cl
)
{
cl
.
def
(
pybind11
::
self
!=
pybind11
::
self
);
}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
!
has_not_equal_operator
<
U
>(
0
)
>::
type
*
=
nullptr
>
void
maybe_has_not_equal_operator
(
Class_
&
)
{}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
has_insertion_operator
<
U
>()
>::
type
*
=
nullptr
>
void
maybe_has_insertion_operator
(
Class_
&
cl
,
std
::
string
name
)
{
cl
.
def
(
"__repr__"
,
[
name
](
typename
vector_binder
<
T
>::
Vector
&
v
)
{
std
::
ostringstream
s
;
s
<<
name
<<
'['
;
for
(
uint
i
=
0
;
i
<
v
.
size
();
++
i
)
{
s
<<
v
[
i
];
if
(
i
!=
v
.
size
()
-
1
)
s
<<
", "
;
}
s
<<
']'
;
return
s
.
str
();
});
}
template
<
typename
U
=
T
,
typename
std
::
enable_if
<
!
has_insertion_operator
<
U
>()
>::
type
*
=
nullptr
>
void
maybe_has_insertion_operator
(
Class_
&
,
char
const
*
)
{}
public:
vector_binder
(
pybind11
::
module
&
m
,
char
const
*
name
)
{
Class_
cl
(
m
,
name
);
cl
.
def
(
pybind11
::
init
<>
());
//maybe_constructible(cl);
maybe_default_constructible
(
cl
);
maybe_copy_constructible
(
cl
);
// Capacity
cl
.
def
(
"empty"
,
&
Vector
::
empty
,
"checks whether the container is empty"
);
cl
.
def
(
"size"
,
&
Vector
::
size
,
"returns the number of elements"
);
cl
.
def
(
"max_size"
,
&
Vector
::
max_size
,
"returns the maximum possible number of elements"
);
cl
.
def
(
"reserve"
,
&
Vector
::
reserve
,
"reserves storage"
);
cl
.
def
(
"capacity"
,
&
Vector
::
capacity
,
"returns the number of elements that can be held in currently allocated storage"
);
cl
.
def
(
"shrink_to_fit"
,
&
Vector
::
shrink_to_fit
,
"reduces memory usage by freeing unused memory"
);
// Modifiers
cl
.
def
(
"clear"
,
&
Vector
::
clear
,
"clears the contents"
);
cl
.
def
(
"push_back"
,
(
void
(
Vector
::*
)(
const
T
&
))
&
Vector
::
push_back
,
"adds an element to the end"
);
cl
.
def
(
"pop_back"
,
&
Vector
::
pop_back
,
"removes the last element"
);
cl
.
def
(
"swap"
,
&
Vector
::
swap
,
"swaps the contents"
);
cl
.
def
(
"erase"
,
[](
Vector
&
v
,
SizeType
i
)
{
if
(
i
>=
v
.
size
())
throw
pybind11
::
index_error
();
v
.
erase
(
v
.
begin
()
+
i
);
},
"erases element at index"
);
// Python friendly bindings
#ifdef PYTHON_ABI_VERSION // Python 3+
cl
.
def
(
"__bool__"
,
[](
Vector
&
v
)
->
bool
{
return
v
.
size
();
});
// checks whether the container has any elements in it
#else
cl
.
def
(
"__nonzero__"
,
[](
Vector
&
v
)
->
bool
{
return
v
.
size
();
});
// checks whether the container has any elements in it
#endif
cl
.
def
(
"__getitem__"
,
[](
Vector
const
&
v
,
SizeType
i
)
{
if
(
i
>=
v
.
size
())
throw
pybind11
::
index_error
();
return
v
[
i
];
});
cl
.
def
(
"__setitem__"
,
[](
Vector
&
v
,
SizeType
i
,
T
const
&
t
)
{
if
(
i
>=
v
.
size
())
throw
pybind11
::
index_error
();
v
[
i
]
=
t
;
});
cl
.
def
(
"__len__"
,
&
Vector
::
size
);
// Comparisons
maybe_has_equal_operator
(
cl
);
maybe_has_not_equal_operator
(
cl
);
// Printing
maybe_has_insertion_operator
(
cl
,
name
);
}
};
NAMESPACE_END
(
pybind11
)
#endif // _INCLUDED_std_binders_h_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment