Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
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
Show 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
example/example14.cpp
example/example15.cpp
example/example16.cpp
example/example17.cpp
example/issues.cpp
)
...
...
example/example.cpp
View file @
eae7744c
...
...
@@ -25,6 +25,7 @@ void init_ex13(py::module &);
void
init_ex14
(
py
::
module
&
);
void
init_ex15
(
py
::
module
&
);
void
init_ex16
(
py
::
module
&
);
void
init_ex17
(
py
::
module
&
);
void
init_issues
(
py
::
module
&
);
#if defined(PYBIND11_TEST_EIGEN)
...
...
@@ -50,6 +51,7 @@ PYBIND11_PLUGIN(example) {
init_ex14
(
m
);
init_ex15
(
m
);
init_ex16
(
m
);
init_ex17
(
m
);
init_issues
(
m
);
#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