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
a3603e6d
"tests/git@developer.sourcefind.cn:gaoqiong/pybind11.git" did not exist on "ec24786eab4d170f21536c92422a59959e14dde4"
Commit
a3603e6d
authored
Sep 28, 2016
by
Trent Houliston
Browse files
Simplify redundant code, conform to style suggestions, improve logic
parent
253e41cc
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
61 additions
and
78 deletions
+61
-78
include/pybind11/chrono.h
include/pybind11/chrono.h
+61
-78
No files found.
include/pybind11/chrono.h
View file @
a3603e6d
...
@@ -12,16 +12,30 @@
...
@@ -12,16 +12,30 @@
#include "pybind11.h"
#include "pybind11.h"
#include <cmath>
#include <cmath>
#include <ctime>
#include <chrono>
#include <chrono>
#include <datetime.h>
#include <datetime.h>
// Backport the PyDateTime_DELTA functions from Python3.3 if required
#ifndef PyDateTime_DELTA_GET_DAYS
#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days)
#endif
#ifndef PyDateTime_DELTA_GET_SECONDS
#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds)
#endif
#ifndef PyDateTime_DELTA_GET_MICROSECONDS
#define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds)
#endif
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
pybind11
)
NAMESPACE_BEGIN
(
detail
)
NAMESPACE_BEGIN
(
detail
)
template
<
typename
Rep
,
typename
Period
>
class
type_caster
<
std
::
chrono
::
duration
<
Rep
,
Period
>>
{
template
<
typename
type
>
class
duration_caster
{
public:
public:
typedef
std
::
chrono
::
duration
<
Rep
,
Period
>
type
;
typedef
typename
type
::
rep
rep
;
typedef
std
::
chrono
::
duration
<
std
::
chrono
::
hours
::
rep
,
std
::
ratio
<
86400
>>
days
;
typedef
typename
type
::
period
period
;
typedef
std
::
chrono
::
duration
<
uint_fast32_t
,
std
::
ratio
<
86400
>>
days
;
bool
load
(
handle
src
,
bool
)
{
bool
load
(
handle
src
,
bool
)
{
using
namespace
std
::
chrono
;
using
namespace
std
::
chrono
;
...
@@ -30,29 +44,40 @@ public:
...
@@ -30,29 +44,40 @@ public:
if
(
!
PyDateTimeAPI
)
{
PyDateTime_IMPORT
;
}
if
(
!
PyDateTimeAPI
)
{
PyDateTime_IMPORT
;
}
if
(
!
src
)
return
false
;
if
(
!
src
)
return
false
;
// If
they have passed us a
datetime.delta object
// If
invoked with
datetime.delta object
if
(
PyDelta_Check
(
src
.
ptr
()))
{
if
(
PyDelta_Check
(
src
.
ptr
()))
{
// The accessor macros for timedelta exist in some versions of python but not others (e.g. Mac OSX default python)
value
=
type
(
duration_cast
<
duration
<
rep
,
period
>>
(
// Therefore we are just doing what the macros do explicitly
days
(
PyDateTime_DELTA_GET_DAYS
(
src
.
ptr
()))
const
PyDateTime_Delta
*
delta
=
reinterpret_cast
<
PyDateTime_Delta
*>
(
src
.
ptr
());
+
seconds
(
PyDateTime_DELTA_GET_SECONDS
(
src
.
ptr
()))
value
=
duration_cast
<
duration
<
Rep
,
Period
>>
(
+
microseconds
(
PyDateTime_DELTA_GET_MICROSECONDS
(
src
.
ptr
()))));
days
(
delta
->
days
)
+
seconds
(
delta
->
seconds
)
+
microseconds
(
delta
->
microseconds
));
return
true
;
return
true
;
}
}
// If
they have passed us
a float we
can
assume it is seconds and convert
// If
invoked with
a float we assume it is seconds and convert
else
if
(
PyFloat_Check
(
src
.
ptr
()))
{
else
if
(
PyFloat_Check
(
src
.
ptr
()))
{
double
val
=
PyFloat_AsDouble
(
src
.
ptr
());
value
=
type
(
duration_cast
<
duration
<
rep
,
period
>>
(
duration
<
double
>
(
PyFloat_AsDouble
(
src
.
ptr
()))));
// Multiply by the reciprocal of the ratio and round
value
=
type
(
std
::
lround
(
val
*
type
::
period
::
den
/
type
::
period
::
num
));
return
true
;
return
true
;
}
}
else
return
false
;
else
return
false
;
}
}
static
handle
cast
(
const
std
::
chrono
::
duration
<
Rep
,
Period
>
&
src
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
// If this is a duration just return it back
static
const
std
::
chrono
::
duration
<
rep
,
period
>&
get_duration
(
const
std
::
chrono
::
duration
<
rep
,
period
>
&
src
)
{
return
src
;
}
// If this is a time_point get the time_since_epoch
template
<
typename
Clock
>
static
std
::
chrono
::
duration
<
rep
,
period
>
get_duration
(
const
std
::
chrono
::
time_point
<
Clock
,
std
::
chrono
::
duration
<
rep
,
period
>>
&
src
)
{
return
src
.
time_since_epoch
();
}
static
handle
cast
(
const
type
&
src
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
using
namespace
std
::
chrono
;
using
namespace
std
::
chrono
;
// Use overloaded function to get our duration from our source
// Works out if it is a duration or time_point and get the duration
auto
d
=
get_duration
(
src
);
// Lazy initialise the PyDateTime import
if
(
!
PyDateTimeAPI
)
{
PyDateTime_IMPORT
;
}
if
(
!
PyDateTimeAPI
)
{
PyDateTime_IMPORT
;
}
// Declare these special duration types so the conversions happen with the correct primitive types (int)
// Declare these special duration types so the conversions happen with the correct primitive types (int)
...
@@ -60,11 +85,11 @@ public:
...
@@ -60,11 +85,11 @@ public:
using
ss_t
=
duration
<
int
,
std
::
ratio
<
1
>>
;
using
ss_t
=
duration
<
int
,
std
::
ratio
<
1
>>
;
using
us_t
=
duration
<
int
,
std
::
micro
>
;
using
us_t
=
duration
<
int
,
std
::
micro
>
;
return
PyDelta_FromDSU
(
return
PyDelta_FromDSU
(
duration_cast
<
dd_t
>
(
d
).
count
(),
duration_cast
<
dd_t
>
(
src
).
count
()
duration_cast
<
ss_t
>
(
d
%
days
(
1
)).
count
(),
,
duration_cast
<
ss_t
>
(
src
%
days
(
1
)).
count
()
duration_cast
<
us_t
>
(
d
%
seconds
(
1
)).
count
());
,
duration_cast
<
us_t
>
(
src
%
seconds
(
1
)).
count
());
}
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"datetime.timedelta"
));
PYBIND11_TYPE_CASTER
(
type
,
_
(
"datetime.timedelta"
));
};
};
...
@@ -89,7 +114,7 @@ public:
...
@@ -89,7 +114,7 @@ public:
cal
.
tm_year
=
PyDateTime_GET_YEAR
(
src
.
ptr
())
-
1900
;
cal
.
tm_year
=
PyDateTime_GET_YEAR
(
src
.
ptr
())
-
1900
;
cal
.
tm_isdst
=
-
1
;
cal
.
tm_isdst
=
-
1
;
value
=
system_clock
::
from_time_t
(
mktime
(
&
cal
))
+
microseconds
(
PyDateTime_DATE_GET_MICROSECOND
(
src
.
ptr
()));
value
=
system_clock
::
from_time_t
(
std
::
mktime
(
&
cal
))
+
microseconds
(
PyDateTime_DATE_GET_MICROSECOND
(
src
.
ptr
()));
return
true
;
return
true
;
}
}
else
return
false
;
else
return
false
;
...
@@ -101,21 +126,21 @@ public:
...
@@ -101,21 +126,21 @@ public:
// Lazy initialise the PyDateTime import
// Lazy initialise the PyDateTime import
if
(
!
PyDateTimeAPI
)
{
PyDateTime_IMPORT
;
}
if
(
!
PyDateTimeAPI
)
{
PyDateTime_IMPORT
;
}
time_t
tt
=
system_clock
::
to_time_t
(
src
);
std
::
time_t
tt
=
system_clock
::
to_time_t
(
src
);
// this function uses static memory so it's best to copy it out asap just in case
// this function uses static memory so it's best to copy it out asap just in case
tm
*
ltime
=
localtime
(
&
tt
);
// otherwise other code that is using localtime may break this (not just python code)
tm
localtime
=
*
ltime
;
std
::
tm
localtime
=
*
std
::
localtime
(
&
tt
)
;
// Declare these special duration types so the conversions happen with the correct primitive types (int)
// Declare these special duration types so the conversions happen with the correct primitive types (int)
using
us_t
=
duration
<
int
,
std
::
micro
>
;
using
us_t
=
duration
<
int
,
std
::
micro
>
;
return
PyDateTime_FromDateAndTime
(
localtime
.
tm_year
+
1900
return
PyDateTime_FromDateAndTime
(
localtime
.
tm_year
+
1900
,
,
localtime
.
tm_mon
+
1
localtime
.
tm_mon
+
1
,
,
localtime
.
tm_mday
localtime
.
tm_mday
,
,
localtime
.
tm_hour
localtime
.
tm_hour
,
,
localtime
.
tm_min
localtime
.
tm_min
,
,
localtime
.
tm_sec
localtime
.
tm_sec
,
,
(
duration_cast
<
us_t
>
(
src
.
time_since_epoch
()
%
seconds
(
1
))).
count
());
(
duration_cast
<
us_t
>
(
src
.
time_since_epoch
()
%
seconds
(
1
))).
count
());
}
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"datetime.datetime"
));
PYBIND11_TYPE_CASTER
(
type
,
_
(
"datetime.datetime"
));
};
};
...
@@ -123,54 +148,12 @@ public:
...
@@ -123,54 +148,12 @@ public:
// Other clocks that are not the system clock are not measured as datetime.datetime objects
// Other clocks that are not the system clock are not measured as datetime.datetime objects
// since they are not measured on calendar time. So instead we just make them timedeltas
// since they are not measured on calendar time. So instead we just make them timedeltas
// Or if they have passed us a time as a float we convert that
// Or if they have passed us a time as a float we convert that
template
<
typename
Clock
,
typename
Duration
>
class
type_caster
<
std
::
chrono
::
time_point
<
Clock
,
Duration
>>
{
template
<
typename
Clock
,
typename
Duration
>
class
type_caster
<
std
::
chrono
::
time_point
<
Clock
,
Duration
>>
public:
:
public
duration_caster
<
std
::
chrono
::
time_point
<
Clock
,
Duration
>>
{
typedef
std
::
chrono
::
time_point
<
Clock
,
Duration
>
type
;
};
typedef
std
::
chrono
::
duration
<
std
::
chrono
::
hours
::
rep
,
std
::
ratio
<
86400
>>
days
;
bool
load
(
handle
src
,
bool
)
{
using
namespace
std
::
chrono
;
if
(
!
PyDateTimeAPI
)
{
PyDateTime_IMPORT
;
}
// If they have passed us a datetime.delta object
if
(
PyDelta_Check
(
src
.
ptr
()))
{
// The accessor macros for timedelta exist in some versions of python but not others (e.g. Mac OSX default python)
// Therefore we are just doing what the macros do explicitly
const
PyDateTime_Delta
*
delta
=
reinterpret_cast
<
PyDateTime_Delta
*>
(
src
.
ptr
());
value
=
time_point
<
Clock
,
Duration
>
(
days
(
delta
->
days
)
+
seconds
(
delta
->
seconds
)
+
microseconds
(
delta
->
microseconds
));
return
true
;
}
// If they have passed us a float we can assume it is seconds and convert
else
if
(
PyFloat_Check
(
src
.
ptr
()))
{
double
val
=
PyFloat_AsDouble
(
src
.
ptr
());
value
=
time_point
<
Clock
,
Duration
>
(
Duration
(
std
::
lround
((
val
/
Clock
::
period
::
num
)
*
Clock
::
period
::
den
)));
return
true
;
}
else
return
false
;
}
static
handle
cast
(
const
std
::
chrono
::
time_point
<
Clock
,
Duration
>
&
src
,
return_value_policy
/* policy */
,
handle
/* parent */
)
{
using
namespace
std
::
chrono
;
// Lazy initialise the PyDateTime import
if
(
!
PyDateTimeAPI
)
{
PyDateTime_IMPORT
;
}
// Declare these special duration types so the conversions happen with the correct primitive types (int)
using
dd_t
=
duration
<
int
,
std
::
ratio
<
86400
>>
;
using
ss_t
=
duration
<
int
,
std
::
ratio
<
1
>>
;
using
us_t
=
duration
<
int
,
std
::
micro
>
;
Duration
d
=
src
.
time_since_epoch
();
return
PyDelta_FromDSU
(
template
<
typename
Rep
,
typename
Period
>
class
type_caster
<
std
::
chrono
::
duration
<
Rep
,
Period
>>
duration_cast
<
dd_t
>
(
d
).
count
()
:
public
duration_caster
<
std
::
chrono
::
duration
<
Rep
,
Period
>>
{
,
duration_cast
<
ss_t
>
(
d
%
days
(
1
)).
count
()
,
duration_cast
<
us_t
>
(
d
%
seconds
(
1
)).
count
());
}
PYBIND11_TYPE_CASTER
(
type
,
_
(
"datetime.timedelta"
));
};
};
NAMESPACE_END
(
detail
)
NAMESPACE_END
(
detail
)
...
...
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