Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
fmt
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
fmt
Commits
f54f3d0f
Commit
f54f3d0f
authored
Dec 07, 2018
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move chrono-specific code to a separate header
parent
bf1f1c73
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
443 additions
and
302 deletions
+443
-302
CMakeLists.txt
CMakeLists.txt
+2
-2
include/fmt/chrono.h
include/fmt/chrono.h
+336
-0
include/fmt/time.h
include/fmt/time.h
+0
-239
test/CMakeLists.txt
test/CMakeLists.txt
+1
-0
test/chrono-test.cc
test/chrono-test.cc
+101
-0
test/gtest-extra-test.cc
test/gtest-extra-test.cc
+2
-2
test/posix-test.cc
test/posix-test.cc
+1
-1
test/time-test.cc
test/time-test.cc
+0
-58
No files found.
CMakeLists.txt
View file @
f54f3d0f
...
@@ -138,8 +138,8 @@ function(add_headers VAR)
...
@@ -138,8 +138,8 @@ function(add_headers VAR)
endfunction
()
endfunction
()
# Define the fmt library, its includes and the needed defines.
# Define the fmt library, its includes and the needed defines.
add_headers
(
FMT_HEADERS c
olor.h core.h format.h format-inl.h locale.h ostream
.h
add_headers
(
FMT_HEADERS c
hrono.h color.h core.h format.h format-inl.h locale
.h
printf.h time.h ranges.h
)
ostream.h
printf.h time.h ranges.h
)
set
(
FMT_SOURCES src/format.cc
)
set
(
FMT_SOURCES src/format.cc
)
if
(
HAVE_OPEN
)
if
(
HAVE_OPEN
)
add_headers
(
FMT_HEADERS posix.h
)
add_headers
(
FMT_HEADERS posix.h
)
...
...
include/fmt/chrono.h
0 → 100644
View file @
f54f3d0f
// Formatting library for C++ - chrono support
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#ifndef FMT_CHRONO_H_
#define FMT_CHRONO_H_
#include "format.h"
#include "locale.h"
#include <chrono>
#include <ctime>
#include <locale>
#include <sstream>
FMT_BEGIN_NAMESPACE
namespace
internal
{
enum
class
numeric_system
{
standard
,
// Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale.
alternative
};
// Parses a put_time-like format string and invokes handler actions.
template
<
typename
Char
,
typename
Handler
>
FMT_CONSTEXPR
const
Char
*
parse_chrono_format
(
const
Char
*
begin
,
const
Char
*
end
,
Handler
&&
handler
)
{
auto
ptr
=
begin
;
while
(
ptr
!=
end
)
{
auto
c
=
*
ptr
;
if
(
c
==
'}'
)
break
;
if
(
c
!=
'%'
)
{
++
ptr
;
continue
;
}
if
(
begin
!=
ptr
)
handler
.
on_text
(
begin
,
ptr
);
++
ptr
;
// consume '%'
if
(
ptr
==
end
)
throw
format_error
(
"invalid format"
);
c
=
*
ptr
++
;
switch
(
c
)
{
case
'%'
:
handler
.
on_text
(
ptr
-
1
,
ptr
);
break
;
// Day of the week:
case
'a'
:
handler
.
on_abbr_weekday
();
break
;
case
'A'
:
handler
.
on_full_weekday
();
break
;
case
'w'
:
handler
.
on_dec0_weekday
(
numeric_system
::
standard
);
break
;
case
'u'
:
handler
.
on_dec1_weekday
(
numeric_system
::
standard
);
break
;
// Month:
case
'b'
:
handler
.
on_abbr_month
();
break
;
case
'B'
:
handler
.
on_full_month
();
break
;
// Hour, minute, second:
case
'H'
:
handler
.
on_24_hour
(
numeric_system
::
standard
);
break
;
case
'I'
:
handler
.
on_12_hour
(
numeric_system
::
standard
);
break
;
case
'M'
:
handler
.
on_minute
(
numeric_system
::
standard
);
break
;
case
'S'
:
handler
.
on_second
(
numeric_system
::
standard
);
break
;
// Other:
case
'c'
:
handler
.
on_std_datetime
();
break
;
case
'x'
:
handler
.
on_loc_date
();
break
;
case
'X'
:
handler
.
on_loc_time
();
break
;
case
'D'
:
handler
.
on_us_date
();
break
;
case
'F'
:
handler
.
on_iso_date
();
break
;
case
'r'
:
handler
.
on_12_hour_time
();
break
;
case
'R'
:
handler
.
on_24_hour_time
();
break
;
// Alternative numeric system:
case
'O'
:
if
(
ptr
==
end
)
throw
format_error
(
"invalid format"
);
c
=
*
ptr
++
;
switch
(
c
)
{
case
'w'
:
handler
.
on_dec0_weekday
(
numeric_system
::
alternative
);
break
;
case
'u'
:
handler
.
on_dec1_weekday
(
numeric_system
::
alternative
);
break
;
case
'H'
:
handler
.
on_24_hour
(
numeric_system
::
alternative
);
break
;
case
'I'
:
handler
.
on_12_hour
(
numeric_system
::
alternative
);
break
;
case
'M'
:
handler
.
on_minute
(
numeric_system
::
alternative
);
break
;
case
'S'
:
handler
.
on_second
(
numeric_system
::
alternative
);
break
;
}
break
;
// TODO: parse more format specifiers
}
begin
=
ptr
;
}
if
(
begin
!=
ptr
)
handler
.
on_text
(
begin
,
ptr
);
return
ptr
;
}
struct
chrono_format_checker
{
template
<
typename
Char
>
void
on_text
(
const
Char
*
,
const
Char
*
)
{}
void
on_abbr_weekday
()
{}
void
on_full_weekday
()
{}
void
on_dec0_weekday
(
numeric_system
)
{}
void
on_dec1_weekday
(
numeric_system
)
{}
void
on_abbr_month
()
{}
void
on_full_month
()
{}
void
on_24_hour
(
numeric_system
)
{}
void
on_12_hour
(
numeric_system
)
{}
void
on_minute
(
numeric_system
)
{}
void
on_second
(
numeric_system
)
{}
void
on_std_datetime
()
{}
void
on_loc_date
()
{}
void
on_loc_time
()
{}
void
on_us_date
()
{}
void
on_iso_date
()
{}
void
on_12_hour_time
()
{}
void
on_24_hour_time
()
{}
};
template
<
typename
Int
>
inline
int
to_int
(
Int
value
)
{
FMT_ASSERT
(
value
>=
(
std
::
numeric_limits
<
int
>::
min
)()
&&
value
<=
(
std
::
numeric_limits
<
int
>::
max
)(),
"invalid value"
);
return
static_cast
<
int
>
(
value
);
}
template
<
typename
FormatContext
>
struct
chrono_formatter
{
FormatContext
&
context
;
typename
FormatContext
::
iterator
out
;
std
::
chrono
::
seconds
s
;
std
::
chrono
::
milliseconds
ms
;
typedef
typename
FormatContext
::
char_type
char_type
;
explicit
chrono_formatter
(
FormatContext
&
ctx
)
:
context
(
ctx
),
out
(
ctx
.
out
())
{}
int
hour
()
const
{
return
to_int
((
s
.
count
()
/
3600
)
%
24
);
}
int
hour12
()
const
{
auto
hour
=
to_int
((
s
.
count
()
/
3600
)
%
12
);
return
hour
>
0
?
hour
:
12
;
}
int
minute
()
const
{
return
to_int
((
s
.
count
()
/
60
)
%
60
);
}
int
second
()
const
{
return
to_int
(
s
.
count
()
%
60
);
}
std
::
tm
time
()
const
{
auto
time
=
std
::
tm
();
time
.
tm_hour
=
hour
();
time
.
tm_min
=
minute
();
time
.
tm_sec
=
second
();
return
time
;
}
std
::
tm
datetime
()
const
{
auto
t
=
time
();
t
.
tm_mday
=
1
;
return
t
;
}
std
::
tm
date
()
const
{
auto
t
=
std
::
tm
();
t
.
tm_mday
=
1
;
return
t
;
}
void
write
(
int
value
,
int
width
)
{
typedef
typename
int_traits
<
int
>::
main_type
main_type
;
main_type
n
=
to_unsigned
(
value
);
int
num_digits
=
static_cast
<
int
>
(
internal
::
count_digits
(
n
));
if
(
width
>
num_digits
)
out
=
std
::
fill_n
(
out
,
width
-
num_digits
,
'0'
);
out
=
format_decimal
<
char_type
>
(
out
,
n
,
num_digits
);
}
void
format_localized
(
const
tm
&
time
,
const
char
*
format
)
{
auto
locale
=
context
.
locale
().
template
get
<
std
::
locale
>();
auto
&
facet
=
std
::
use_facet
<
std
::
time_put
<
char_type
>>
(
locale
);
std
::
basic_ostringstream
<
char_type
>
os
;
os
.
imbue
(
locale
);
facet
.
put
(
os
,
os
,
' '
,
&
time
,
format
,
format
+
std
::
strlen
(
format
));
auto
str
=
os
.
str
();
std
::
copy
(
str
.
begin
(),
str
.
end
(),
out
);
}
void
on_text
(
const
char_type
*
begin
,
const
char_type
*
end
)
{
std
::
copy
(
begin
,
end
,
out
);
}
void
on_abbr_weekday
()
{}
void
on_full_weekday
()
{}
void
on_dec0_weekday
(
numeric_system
)
{}
void
on_dec1_weekday
(
numeric_system
)
{}
void
on_abbr_month
()
{}
void
on_full_month
()
{}
void
on_24_hour
(
numeric_system
ns
)
{
if
(
ns
==
numeric_system
::
standard
)
return
write
(
hour
(),
2
);
auto
time
=
tm
();
time
.
tm_hour
=
hour
();
format_localized
(
time
,
"%OH"
);
}
void
on_12_hour
(
numeric_system
ns
)
{
if
(
ns
==
numeric_system
::
standard
)
return
write
(
hour12
(),
2
);
auto
time
=
tm
();
time
.
tm_hour
=
hour
();
format_localized
(
time
,
"%OI"
);
}
void
on_minute
(
numeric_system
ns
)
{
if
(
ns
==
numeric_system
::
standard
)
return
write
(
minute
(),
2
);
auto
time
=
tm
();
time
.
tm_min
=
minute
();
format_localized
(
time
,
"%OM"
);
}
void
on_second
(
numeric_system
ns
)
{
if
(
ns
==
numeric_system
::
standard
)
{
write
(
second
(),
2
);
if
(
ms
!=
std
::
chrono
::
milliseconds
(
0
))
{
*
out
++
=
'.'
;
write
(
to_int
(
ms
.
count
()),
3
);
}
return
;
}
auto
time
=
tm
();
time
.
tm_sec
=
second
();
format_localized
(
time
,
"%OS"
);
}
void
on_std_datetime
()
{
format_localized
(
datetime
(),
"%c"
);
}
void
on_loc_date
()
{
format_localized
(
date
(),
"%x"
);
}
void
on_loc_time
()
{
format_localized
(
datetime
(),
"%X"
);
}
void
on_us_date
()
{
write
(
1
,
2
);
*
out
++
=
'/'
;
write
(
0
,
2
);
*
out
++
=
'/'
;
write
(
0
,
2
);
}
void
on_iso_date
()
{
write
(
1
,
4
);
*
out
++
=
'-'
;
write
(
0
,
2
);
*
out
++
=
'-'
;
write
(
0
,
2
);
}
void
on_12_hour_time
()
{
format_localized
(
time
(),
"%r"
);
}
void
on_24_hour_time
()
{
write
(
hour
(),
2
);
*
out
++
=
':'
;
write
(
minute
(),
2
);
}
};
}
// namespace internal
template
<
typename
Rep
,
typename
Period
,
typename
Char
>
struct
formatter
<
std
::
chrono
::
duration
<
Rep
,
Period
>
,
Char
>
{
mutable
basic_string_view
<
Char
>
format_str
;
typedef
std
::
chrono
::
duration
<
Rep
,
Period
>
duration
;
FMT_CONSTEXPR
auto
parse
(
basic_parse_context
<
Char
>
&
ctx
)
->
decltype
(
ctx
.
begin
())
{
auto
begin
=
ctx
.
begin
(),
end
=
ctx
.
end
();
end
=
parse_chrono_format
(
begin
,
end
,
internal
::
chrono_format_checker
());
format_str
=
basic_string_view
<
Char
>
(
&*
begin
,
end
-
begin
);
return
end
;
}
template
<
typename
FormatContext
>
auto
format
(
const
duration
&
d
,
FormatContext
&
ctx
)
->
decltype
(
ctx
.
out
())
{
internal
::
chrono_formatter
<
FormatContext
>
f
(
ctx
);
f
.
s
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
seconds
>
(
d
);
f
.
ms
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
d
-
f
.
s
);
parse_chrono_format
(
format_str
.
begin
(),
format_str
.
end
(),
f
);
return
f
.
out
;
}
};
FMT_END_NAMESPACE
#endif // FMT_CHRONO_H_
include/fmt/time.h
View file @
f54f3d0f
...
@@ -12,11 +12,6 @@
...
@@ -12,11 +12,6 @@
#include <ctime>
#include <ctime>
#include <locale>
#include <locale>
#if FMT_HAS_INCLUDE(<chrono>)
# include <chrono>
# include <sstream>
#endif
FMT_BEGIN_NAMESPACE
FMT_BEGIN_NAMESPACE
// Prevents expansion of a preceding token as a function-style macro.
// Prevents expansion of a preceding token as a function-style macro.
...
@@ -28,242 +23,8 @@ inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
...
@@ -28,242 +23,8 @@ inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
inline
null
<>
localtime_s
(...)
{
return
null
<>
();
}
inline
null
<>
localtime_s
(...)
{
return
null
<>
();
}
inline
null
<>
gmtime_r
(...)
{
return
null
<>
();
}
inline
null
<>
gmtime_r
(...)
{
return
null
<>
();
}
inline
null
<>
gmtime_s
(...)
{
return
null
<>
();
}
inline
null
<>
gmtime_s
(...)
{
return
null
<>
();
}
enum
class
numeric_system
{
standard
,
// Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale.
alternative
};
// Parses a put_time-like format string and invokes handler actions.
template
<
typename
Char
,
typename
Handler
>
FMT_CONSTEXPR
const
Char
*
parse_chrono_format
(
const
Char
*
begin
,
const
Char
*
end
,
Handler
&&
handler
)
{
auto
ptr
=
begin
;
while
(
ptr
!=
end
)
{
auto
c
=
*
ptr
;
if
(
c
==
'}'
)
break
;
if
(
c
!=
'%'
)
{
++
ptr
;
continue
;
}
if
(
begin
!=
ptr
)
handler
.
on_text
(
begin
,
ptr
);
++
ptr
;
// consume '%'
if
(
ptr
==
end
)
throw
format_error
(
"invalid format"
);
c
=
*
ptr
++
;
switch
(
c
)
{
case
'%'
:
handler
.
on_text
(
ptr
-
1
,
ptr
);
break
;
// Day of the week:
case
'a'
:
handler
.
on_abbr_weekday
();
break
;
case
'A'
:
handler
.
on_full_weekday
();
break
;
case
'w'
:
handler
.
on_dec0_weekday
(
numeric_system
::
standard
);
break
;
case
'u'
:
handler
.
on_dec1_weekday
(
numeric_system
::
standard
);
break
;
// Month:
case
'b'
:
handler
.
on_abbr_month
();
break
;
case
'B'
:
handler
.
on_full_month
();
break
;
// Hour, minute, second:
case
'H'
:
handler
.
on_24_hour
(
numeric_system
::
standard
);
break
;
case
'I'
:
handler
.
on_12_hour
(
numeric_system
::
standard
);
break
;
case
'M'
:
handler
.
on_minute
(
numeric_system
::
standard
);
break
;
case
'S'
:
handler
.
on_second
(
numeric_system
::
standard
);
break
;
// Alternative numeric system:
case
'O'
:
if
(
ptr
==
end
)
throw
format_error
(
"invalid format"
);
c
=
*
ptr
++
;
switch
(
c
)
{
case
'w'
:
handler
.
on_dec0_weekday
(
numeric_system
::
alternative
);
break
;
case
'u'
:
handler
.
on_dec1_weekday
(
numeric_system
::
alternative
);
break
;
case
'H'
:
handler
.
on_24_hour
(
numeric_system
::
alternative
);
break
;
case
'I'
:
handler
.
on_12_hour
(
numeric_system
::
alternative
);
break
;
case
'M'
:
handler
.
on_minute
(
numeric_system
::
alternative
);
break
;
case
'S'
:
handler
.
on_second
(
numeric_system
::
alternative
);
break
;
}
break
;
// TODO: parse more format specifiers
}
begin
=
ptr
;
}
if
(
begin
!=
ptr
)
handler
.
on_text
(
begin
,
ptr
);
return
ptr
;
}
struct
chrono_format_checker
{
template
<
typename
Char
>
void
on_text
(
const
Char
*
,
const
Char
*
)
{}
void
on_abbr_weekday
()
{}
void
on_full_weekday
()
{}
void
on_dec0_weekday
(
numeric_system
)
{}
void
on_dec1_weekday
(
numeric_system
)
{}
void
on_abbr_month
()
{}
void
on_full_month
()
{}
void
on_24_hour
(
numeric_system
)
{}
void
on_12_hour
(
numeric_system
)
{}
void
on_minute
(
numeric_system
)
{}
void
on_second
(
numeric_system
)
{}
};
}
// namespace internal
}
// namespace internal
#ifdef __cpp_lib_chrono
namespace
internal
{
template
<
typename
Int
>
inline
int
to_int
(
Int
value
)
{
FMT_ASSERT
(
value
>=
(
std
::
numeric_limits
<
int
>::
min
)()
&&
value
<=
(
std
::
numeric_limits
<
int
>::
max
)(),
"invalid value"
);
return
static_cast
<
int
>
(
value
);
}
template
<
typename
FormatContext
>
struct
chrono_formatter
{
FormatContext
&
context
;
typename
FormatContext
::
iterator
out
;
std
::
chrono
::
seconds
s
;
std
::
chrono
::
milliseconds
ms
;
using
char_type
=
typename
FormatContext
::
char_type
;
explicit
chrono_formatter
(
FormatContext
&
ctx
)
:
context
(
ctx
),
out
(
ctx
.
out
())
{}
void
write
(
int
value
,
int
width
)
{
typedef
typename
int_traits
<
int
>::
main_type
main_type
;
main_type
n
=
to_unsigned
(
value
);
int
num_digits
=
static_cast
<
int
>
(
internal
::
count_digits
(
n
));
if
(
width
>
num_digits
)
out
=
std
::
fill_n
(
out
,
width
-
num_digits
,
'0'
);
out
=
format_decimal
<
char_type
>
(
out
,
n
,
num_digits
);
}
void
format_localized
(
const
tm
&
time
,
char
format
)
{
auto
locale
=
context
.
locale
().
template
get
<
std
::
locale
>();
auto
&
facet
=
std
::
use_facet
<
std
::
time_put
<
char_type
>>
(
locale
);
std
::
basic_ostringstream
<
char_type
>
os
;
os
.
imbue
(
locale
);
const
char
format_str
[]
=
{
'%'
,
'O'
,
format
};
facet
.
put
(
os
,
os
,
' '
,
&
time
,
format_str
,
format_str
+
sizeof
(
format_str
));
auto
str
=
os
.
str
();
std
::
copy
(
str
.
begin
(),
str
.
end
(),
out
);
}
void
on_text
(
const
char_type
*
begin
,
const
char_type
*
end
)
{
std
::
copy
(
begin
,
end
,
out
);
}
void
on_abbr_weekday
()
{}
void
on_full_weekday
()
{}
void
on_dec0_weekday
(
numeric_system
)
{}
void
on_dec1_weekday
(
numeric_system
)
{}
void
on_abbr_month
()
{}
void
on_full_month
()
{}
void
on_24_hour
(
numeric_system
ns
)
{
auto
hour
=
to_int
((
s
.
count
()
/
3600
)
%
24
);
if
(
ns
==
numeric_system
::
standard
)
return
write
(
hour
,
2
);
auto
time
=
tm
();
time
.
tm_hour
=
hour
;
format_localized
(
time
,
'H'
);
}
void
on_12_hour
(
numeric_system
ns
)
{
auto
hour
=
to_int
((
s
.
count
()
/
3600
)
%
12
);
hour
=
hour
>
0
?
hour
:
12
;
if
(
ns
==
numeric_system
::
standard
)
return
write
(
hour
,
2
);
auto
time
=
tm
();
time
.
tm_hour
=
hour
;
format_localized
(
time
,
'I'
);
}
void
on_minute
(
numeric_system
ns
)
{
auto
minute
=
to_int
((
s
.
count
()
/
60
)
%
60
);
if
(
ns
==
numeric_system
::
standard
)
return
write
(
minute
,
2
);
auto
time
=
tm
();
time
.
tm_min
=
minute
;
format_localized
(
time
,
'M'
);
}
void
on_second
(
numeric_system
ns
)
{
auto
second
=
to_int
(
s
.
count
()
%
60
);
if
(
ns
==
numeric_system
::
standard
)
{
write
(
second
,
2
);
if
(
ms
!=
std
::
chrono
::
milliseconds
())
{
*
out
++
=
'.'
;
write
(
to_int
(
ms
.
count
()),
3
);
}
return
;
}
auto
time
=
tm
();
time
.
tm_sec
=
second
;
format_localized
(
time
,
'S'
);
}
};
}
// namespace internal
template
<
typename
Rep
,
typename
Period
,
typename
Char
>
struct
formatter
<
std
::
chrono
::
duration
<
Rep
,
Period
>
,
Char
>
{
mutable
basic_string_view
<
Char
>
format_str
;
using
Duration
=
std
::
chrono
::
duration
<
Rep
,
Period
>
;
FMT_CONSTEXPR
auto
parse
(
basic_parse_context
<
Char
>
&
ctx
)
->
decltype
(
ctx
.
begin
())
{
auto
begin
=
ctx
.
begin
(),
end
=
ctx
.
end
();
end
=
parse_chrono_format
(
begin
,
end
,
internal
::
chrono_format_checker
());
format_str
=
basic_string_view
<
Char
>
(
&*
begin
,
end
-
begin
);
return
end
;
}
template
<
typename
FormatContext
>
auto
format
(
const
Duration
&
d
,
FormatContext
&
ctx
)
->
decltype
(
ctx
.
out
())
{
internal
::
chrono_formatter
<
FormatContext
>
f
(
ctx
);
f
.
s
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
seconds
>
(
d
);
f
.
ms
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
d
-
f
.
s
);
parse_chrono_format
(
format_str
.
begin
(),
format_str
.
end
(),
f
);
return
f
.
out
;
}
};
#endif // __cpp_lib_chrono
// Thread-safe replacement for std::localtime
// Thread-safe replacement for std::localtime
inline
std
::
tm
localtime
(
std
::
time_t
time
)
{
inline
std
::
tm
localtime
(
std
::
time_t
time
)
{
struct
dispatcher
{
struct
dispatcher
{
...
...
test/CMakeLists.txt
View file @
f54f3d0f
...
@@ -85,6 +85,7 @@ function(add_fmt_test name)
...
@@ -85,6 +85,7 @@ function(add_fmt_test name)
endfunction
()
endfunction
()
add_fmt_test
(
assert-test
)
add_fmt_test
(
assert-test
)
add_fmt_test
(
chrono-test
)
add_fmt_test
(
core-test
)
add_fmt_test
(
core-test
)
add_fmt_test
(
gtest-extra-test
)
add_fmt_test
(
gtest-extra-test
)
add_fmt_test
(
format-test mock-allocator.h
)
add_fmt_test
(
format-test mock-allocator.h
)
...
...
test/chrono-test.cc
0 → 100644
View file @
f54f3d0f
// Formatting library for C++ - time formatting tests
//
// Copyright (c) 2012 - present, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
#include "fmt/chrono.h"
#include "gtest.h"
#include <iomanip>
std
::
tm
make_tm
()
{
auto
time
=
std
::
tm
();
time
.
tm_mday
=
1
;
return
time
;
}
std
::
tm
make_hour
(
int
h
)
{
auto
time
=
make_tm
();
time
.
tm_hour
=
h
;
return
time
;
}
std
::
tm
make_minute
(
int
m
)
{
auto
time
=
make_tm
();
time
.
tm_min
=
m
;
return
time
;
}
std
::
tm
make_second
(
int
s
)
{
auto
time
=
make_tm
();
time
.
tm_sec
=
s
;
return
time
;
}
std
::
string
format_tm
(
const
std
::
tm
&
time
,
const
char
*
spec
,
const
std
::
locale
&
loc
)
{
auto
&
facet
=
std
::
use_facet
<
std
::
time_put
<
char
>>
(
loc
);
std
::
ostringstream
os
;
os
.
imbue
(
loc
);
facet
.
put
(
os
,
os
,
' '
,
&
time
,
spec
,
spec
+
std
::
strlen
(
spec
));
return
os
.
str
();
}
#define EXPECT_TIME(spec, time, duration) { \
std::locale loc("ja_JP.utf8"); \
EXPECT_EQ(format_tm(time, spec, loc), \
fmt::format(loc, "{:" spec "}", duration)); \
}
TEST
(
ChronoTest
,
Format
)
{
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%S}"
,
std
::
chrono
::
seconds
(
0
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%S}"
,
std
::
chrono
::
seconds
(
60
)));
EXPECT_EQ
(
"42"
,
fmt
::
format
(
"{:%S}"
,
std
::
chrono
::
seconds
(
42
)));
EXPECT_EQ
(
"01.234"
,
fmt
::
format
(
"{:%S}"
,
std
::
chrono
::
milliseconds
(
1234
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%M}"
,
std
::
chrono
::
minutes
(
0
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%M}"
,
std
::
chrono
::
minutes
(
60
)));
EXPECT_EQ
(
"42"
,
fmt
::
format
(
"{:%M}"
,
std
::
chrono
::
minutes
(
42
)));
EXPECT_EQ
(
"01"
,
fmt
::
format
(
"{:%M}"
,
std
::
chrono
::
seconds
(
61
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%H}"
,
std
::
chrono
::
hours
(
0
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%H}"
,
std
::
chrono
::
hours
(
24
)));
EXPECT_EQ
(
"14"
,
fmt
::
format
(
"{:%H}"
,
std
::
chrono
::
hours
(
14
)));
EXPECT_EQ
(
"01"
,
fmt
::
format
(
"{:%H}"
,
std
::
chrono
::
minutes
(
61
)));
EXPECT_EQ
(
"12"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
0
)));
EXPECT_EQ
(
"12"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
12
)));
EXPECT_EQ
(
"12"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
24
)));
EXPECT_EQ
(
"04"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
4
)));
EXPECT_EQ
(
"02"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
14
)));
EXPECT_EQ
(
"03:25:45"
,
fmt
::
format
(
"{:%H:%M:%S}"
,
std
::
chrono
::
seconds
(
12345
)));
EXPECT_EQ
(
"01/00/00"
,
fmt
::
format
(
"{:%D}"
,
std
::
chrono
::
seconds
()));
EXPECT_EQ
(
"0001-00-00"
,
fmt
::
format
(
"{:%F}"
,
std
::
chrono
::
seconds
()));
EXPECT_EQ
(
"03:25"
,
fmt
::
format
(
"{:%R}"
,
std
::
chrono
::
seconds
(
12345
)));
}
TEST
(
ChronoTest
,
Locale
)
{
const
char
*
loc_name
=
"ja_JP.utf8"
;
bool
has_locale
=
false
;
std
::
locale
loc
;
try
{
loc
=
std
::
locale
(
loc_name
);
has_locale
=
true
;
}
catch
(
const
std
::
runtime_error
&
)
{}
if
(
!
has_locale
)
{
fmt
::
print
(
"{} locale is missing.
\n
"
,
loc_name
);
return
;
}
EXPECT_TIME
(
"%OH"
,
make_hour
(
14
),
std
::
chrono
::
hours
(
14
));
EXPECT_TIME
(
"%OI"
,
make_hour
(
14
),
std
::
chrono
::
hours
(
14
));
EXPECT_TIME
(
"%OM"
,
make_minute
(
42
),
std
::
chrono
::
minutes
(
42
));
EXPECT_TIME
(
"%OS"
,
make_second
(
42
),
std
::
chrono
::
seconds
(
42
));
auto
time
=
make_tm
();
time
.
tm_hour
=
3
;
time
.
tm_min
=
25
;
time
.
tm_sec
=
45
;
EXPECT_TIME
(
"%c"
,
time
,
std
::
chrono
::
seconds
(
12345
));
EXPECT_TIME
(
"%x"
,
time
,
std
::
chrono
::
seconds
(
12345
));
EXPECT_TIME
(
"%X"
,
time
,
std
::
chrono
::
seconds
(
12345
));
EXPECT_TIME
(
"%r"
,
time
,
std
::
chrono
::
seconds
(
12345
));
}
test/gtest-extra-test.cc
View file @
f54f3d0f
...
@@ -311,8 +311,8 @@ using fmt::error_code;
...
@@ -311,8 +311,8 @@ using fmt::error_code;
using
fmt
::
file
;
using
fmt
::
file
;
TEST
(
ErrorCodeTest
,
Ctor
)
{
TEST
(
ErrorCodeTest
,
Ctor
)
{
EXPECT_EQ
(
0
,
error_code
().
get
()
);
EXPECT_EQ
(
error_code
().
get
(),
0
);
EXPECT_EQ
(
42
,
error_code
(
42
).
get
()
);
EXPECT_EQ
(
error_code
(
42
).
get
(),
42
);
}
}
TEST
(
OutputRedirectTest
,
ScopedRedirect
)
{
TEST
(
OutputRedirectTest
,
ScopedRedirect
)
{
...
...
test/posix-test.cc
View file @
f54f3d0f
...
@@ -334,7 +334,7 @@ TEST(FileTest, Dup2NoExcept) {
...
@@ -334,7 +334,7 @@ TEST(FileTest, Dup2NoExcept) {
file
copy
=
open_file
();
file
copy
=
open_file
();
error_code
ec
;
error_code
ec
;
f
.
dup2
(
copy
.
descriptor
(),
ec
);
f
.
dup2
(
copy
.
descriptor
(),
ec
);
EXPECT_EQ
(
0
,
ec
.
get
()
);
EXPECT_EQ
(
ec
.
get
(),
0
);
EXPECT_NE
(
f
.
descriptor
(),
copy
.
descriptor
());
EXPECT_NE
(
f
.
descriptor
(),
copy
.
descriptor
());
EXPECT_READ
(
copy
,
FILE_CONTENT
);
EXPECT_READ
(
copy
,
FILE_CONTENT
);
}
}
...
...
test/time-test.cc
View file @
f54f3d0f
...
@@ -66,61 +66,3 @@ TEST(TimeTest, GMTime) {
...
@@ -66,61 +66,3 @@ TEST(TimeTest, GMTime) {
std
::
tm
tm
=
*
std
::
gmtime
(
&
t
);
std
::
tm
tm
=
*
std
::
gmtime
(
&
t
);
EXPECT_TRUE
(
EqualTime
(
tm
,
fmt
::
gmtime
(
t
)));
EXPECT_TRUE
(
EqualTime
(
tm
,
fmt
::
gmtime
(
t
)));
}
}
#ifdef __cpp_lib_chrono
TEST
(
TimeTest
,
Chrono
)
{
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%S}"
,
std
::
chrono
::
seconds
(
0
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%S}"
,
std
::
chrono
::
seconds
(
60
)));
EXPECT_EQ
(
"42"
,
fmt
::
format
(
"{:%S}"
,
std
::
chrono
::
seconds
(
42
)));
EXPECT_EQ
(
"01.234"
,
fmt
::
format
(
"{:%S}"
,
std
::
chrono
::
milliseconds
(
1234
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%M}"
,
std
::
chrono
::
minutes
(
0
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%M}"
,
std
::
chrono
::
minutes
(
60
)));
EXPECT_EQ
(
"42"
,
fmt
::
format
(
"{:%M}"
,
std
::
chrono
::
minutes
(
42
)));
EXPECT_EQ
(
"01"
,
fmt
::
format
(
"{:%M}"
,
std
::
chrono
::
seconds
(
61
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%H}"
,
std
::
chrono
::
hours
(
0
)));
EXPECT_EQ
(
"00"
,
fmt
::
format
(
"{:%H}"
,
std
::
chrono
::
hours
(
24
)));
EXPECT_EQ
(
"14"
,
fmt
::
format
(
"{:%H}"
,
std
::
chrono
::
hours
(
14
)));
EXPECT_EQ
(
"01"
,
fmt
::
format
(
"{:%H}"
,
std
::
chrono
::
minutes
(
61
)));
EXPECT_EQ
(
"12"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
0
)));
EXPECT_EQ
(
"12"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
12
)));
EXPECT_EQ
(
"12"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
24
)));
EXPECT_EQ
(
"04"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
4
)));
EXPECT_EQ
(
"02"
,
fmt
::
format
(
"{:%I}"
,
std
::
chrono
::
hours
(
14
)));
EXPECT_EQ
(
"03:25:45"
,
fmt
::
format
(
"{:%H:%M:%S}"
,
std
::
chrono
::
seconds
(
12345
)));
}
std
::
string
format_tm
(
const
std
::
tm
&
time
,
const
char
*
spec
,
const
std
::
locale
&
loc
)
{
std
::
ostringstream
os
;
os
.
imbue
(
loc
);
os
<<
std
::
put_time
(
&
time
,
spec
);
return
os
.
str
();
}
#define EXPECT_TIME(spec, field, value, duration) { \
auto time = std::tm(); \
time.field = value; \
std::locale("ja_JP.utf8"); \
EXPECT_EQ(format_tm(time, spec, loc), \
fmt::format(loc, "{:" spec "}", std::chrono::duration(value))); \
}
TEST
(
TimeTest
,
ChronoLocale
)
{
const
char
*
loc_name
=
"ja_JP.utf8"
;
bool
has_locale
=
false
;
std
::
locale
loc
;
try
{
loc
=
std
::
locale
(
loc_name
);
has_locale
=
true
;
}
catch
(
const
std
::
runtime_error
&
)
{}
if
(
!
has_locale
)
{
fmt
::
print
(
"{} locale is missing.
\n
"
,
loc_name
);
return
;
}
EXPECT_TIME
(
"%OH"
,
tm_hour
,
14
,
hours
);
EXPECT_TIME
(
"%OI"
,
tm_hour
,
14
,
hours
);
EXPECT_TIME
(
"%OM"
,
tm_min
,
42
,
minutes
);
EXPECT_TIME
(
"%OS"
,
tm_sec
,
42
,
seconds
);
}
#endif
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