Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pistache
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
pistache
Commits
86ef2a43
Commit
86ef2a43
authored
Jan 13, 2021
by
Jacob Bogdanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Upgrade to C++17 and use std::optional
Fixes #858 Replace `Pistache::Optional` with `std::optional`
parent
5b5e374d
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
121 additions
and
764 deletions
+121
-764
CMakeLists.txt
CMakeLists.txt
+2
-2
README.md
README.md
+8
-8
debian/control
debian/control
+2
-2
include/pistache/cookie.h
include/pistache/cookie.h
+5
-5
include/pistache/description.h
include/pistache/description.h
+4
-4
include/pistache/http.h
include/pistache/http.h
+1
-1
include/pistache/http_headers.h
include/pistache/http_headers.h
+1
-1
include/pistache/mime.h
include/pistache/mime.h
+4
-5
include/pistache/optional.h
include/pistache/optional.h
+0
-467
include/pistache/thirdparty/date.h
include/pistache/thirdparty/date.h
+7
-7
include/pistache/transport.h
include/pistache/transport.h
+1
-1
src/common/cookie.cc
src/common/cookie.cc
+26
-17
src/common/description.cc
src/common/description.cc
+6
-6
src/common/http.cc
src/common/http.cc
+3
-3
src/common/http_headers.cc
src/common/http_headers.cc
+3
-3
src/common/mime.cc
src/common/mime.cc
+9
-7
tests/CMakeLists.txt
tests/CMakeLists.txt
+0
-1
tests/cookie_test.cc
tests/cookie_test.cc
+15
-15
tests/headers_test.cc
tests/headers_test.cc
+9
-9
tests/http_client_test.cc
tests/http_client_test.cc
+1
-1
tests/mime_test.cc
tests/mime_test.cc
+14
-14
tests/optional_test.cc
tests/optional_test.cc
+0
-185
No files found.
CMakeLists.txt
View file @
86ef2a43
...
...
@@ -2,8 +2,8 @@ cmake_minimum_required (VERSION 3.11)
set
(
CMAKE_BUILD_TYPE_INIT Release
)
# CMAKE Pin cxx compiler to CXX1
4 until update to CXX1
7
set
(
CMAKE_CXX_STANDARD 1
4
)
# CMAKE Pin cxx compiler to CXX17
set
(
CMAKE_CXX_STANDARD 1
7
)
set
(
CMAKE_CXX_STANDARD_REQUIRED ON
)
set
(
CMAKE_CXX_EXTENSIONS OFF
)
...
...
README.md
View file @
86ef2a43
...
...
@@ -4,7 +4,7 @@
[

](https://travis-ci.org/pistacheio/pistache)
Pistache is a modern and elegant HTTP and REST framework for C++. It is entirely written in pure-C++1
4
and provides a clear and pleasant API.
Pistache is a modern and elegant HTTP and REST framework for C++. It is entirely written in pure-C++1
7
and provides a clear and pleasant API.
## Documentation
...
...
@@ -215,7 +215,7 @@ Be patient, async_test can take some time before completing. And that's it, now
Some other Meson options:
| Option | Default | Description |
|
-------------------------------|-------------|------------------------------------------------
|
|
----------------------------- | ------- | ----------------------------------------------
|
| PISTACHE_USE_SSL | False | Build server with SSL support |
| PISTACHE_BUILD_TESTS | False | Build all of the unit tests |
| PISTACHE_ENABLE_NETWORK_TESTS | True | Run unit tests requiring remote network access |
...
...
debian/control
View file @
86ef2a43
...
...
@@ -32,7 +32,7 @@ Depends:
rapidjson-dev (>= 1.1.0)
Description: elegant C++ REST framework
Pistache is a C++ REST framework originally written by Mathieu Stefani at
Datacratic, since maintained by other volunteers. It is written in pure C++1
4
Datacratic, since maintained by other volunteers. It is written in pure C++1
7
with no external dependency and provides a low-level HTTP abstraction.
.
Pistache provides both an HTTP client and server that can be used to create and
...
...
@@ -51,7 +51,7 @@ Depends:
${shlibs:Depends}
Description: elegant C++ REST framework
Pistache is a C++ REST framework originally written by Mathieu Stefani at
Datacratic, since maintained by other volunteers. It is written in pure C++1
4
Datacratic, since maintained by other volunteers. It is written in pure C++1
7
with no external dependency and provides a low-level HTTP abstraction.
.
Pistache provides both an HTTP client and server that can be used to create and
...
...
include/pistache/cookie.h
View file @
86ef2a43
...
...
@@ -9,12 +9,12 @@
#include <ctime>
#include <list>
#include <map>
#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <pistache/http_defs.h>
#include <pistache/optional.h>
namespace
Pistache
{
...
...
@@ -30,11 +30,11 @@ namespace Pistache
std
::
string
name
;
std
::
string
value
;
O
ptional
<
std
::
string
>
path
;
O
ptional
<
std
::
string
>
domain
;
O
ptional
<
FullDate
>
expires
;
std
::
o
ptional
<
std
::
string
>
path
;
std
::
o
ptional
<
std
::
string
>
domain
;
std
::
o
ptional
<
FullDate
>
expires
;
O
ptional
<
int
>
maxAge
;
std
::
o
ptional
<
int
>
maxAge
;
bool
secure
;
bool
httpOnly
;
...
...
include/pistache/description.h
View file @
86ef2a43
...
...
@@ -9,6 +9,7 @@
#include <algorithm>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <type_traits>
#include <vector>
...
...
@@ -16,7 +17,6 @@
#include <pistache/http_defs.h>
#include <pistache/iterator_adapter.h>
#include <pistache/mime.h>
#include <pistache/optional.h>
#include <pistache/router.h>
namespace
Pistache
...
...
@@ -154,8 +154,8 @@ namespace Pistache
std
::
string
description
;
std
::
string
termsOfService
;
O
ptional
<
Contact
>
contact
;
O
ptional
<
License
>
license
;
std
::
o
ptional
<
Contact
>
contact
;
std
::
o
ptional
<
License
>
license
;
};
struct
InfoBuilder
...
...
@@ -305,7 +305,7 @@ namespace Pistache
{
}
Group
paths
(
const
std
::
string
&
name
)
const
;
O
ptional
<
Path
>
path
(
const
std
::
string
&
name
,
Http
::
Method
method
)
const
;
std
::
o
ptional
<
Path
>
path
(
const
std
::
string
&
name
,
Http
::
Method
method
)
const
;
group_iterator
add
(
Path
path
);
...
...
include/pistache/http.h
View file @
86ef2a43
...
...
@@ -125,7 +125,7 @@ namespace Pistache
std
::
initializer_list
<
std
::
pair
<
const
std
::
string
,
std
::
string
>>
params
);
void
add
(
std
::
string
name
,
std
::
string
value
);
O
ptional
<
std
::
string
>
get
(
const
std
::
string
&
name
)
const
;
std
::
o
ptional
<
std
::
string
>
get
(
const
std
::
string
&
name
)
const
;
bool
has
(
const
std
::
string
&
name
)
const
;
// Return empty string or "?key1=value1&key2=value2" if query exist
std
::
string
as_str
()
const
;
...
...
include/pistache/http_headers.h
View file @
86ef2a43
...
...
@@ -101,7 +101,7 @@ namespace Pistache
std
::
shared_ptr
<
const
Header
>
tryGet
(
const
std
::
string
&
name
)
const
;
std
::
shared_ptr
<
Header
>
tryGet
(
const
std
::
string
&
name
);
O
ptional
<
Raw
>
tryGetRaw
(
const
std
::
string
&
name
)
const
;
std
::
o
ptional
<
Raw
>
tryGetRaw
(
const
std
::
string
&
name
)
const
;
template
<
typename
H
>
typename
std
::
enable_if
<
IsHeader
<
H
>::
value
,
bool
>::
type
has
()
const
...
...
include/pistache/mime.h
View file @
86ef2a43
...
...
@@ -8,12 +8,11 @@
#include <cassert>
#include <cmath>
#include <optional>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <pistache/optional.h>
namespace
Pistache
{
namespace
Http
...
...
@@ -197,10 +196,10 @@ namespace Pistache
std
::
string
raw
()
const
{
return
raw_
;
}
const
O
ptional
<
Q
>&
q
()
const
{
return
q_
;
}
const
std
::
o
ptional
<
Q
>&
q
()
const
{
return
q_
;
}
void
setQuality
(
Q
quality
);
O
ptional
<
std
::
string
>
getParam
(
const
std
::
string
&
name
)
const
;
std
::
o
ptional
<
std
::
string
>
getParam
(
const
std
::
string
&
name
)
const
;
void
setParam
(
const
std
::
string
&
name
,
std
::
string
value
);
std
::
string
toString
()
const
;
...
...
@@ -234,7 +233,7 @@ namespace Pistache
std
::
unordered_map
<
std
::
string
,
std
::
string
>
params
;
O
ptional
<
Q
>
q_
;
std
::
o
ptional
<
Q
>
q_
;
};
inline
bool
operator
==
(
const
MediaType
&
lhs
,
const
MediaType
&
rhs
)
...
...
include/pistache/optional.h
deleted
100644 → 0
View file @
5b5e374d
/* optional.h
Mathieu Stefani, 27 August 2015
An algebraic data type that can either represent Some Value or None.
This type is the equivalent of the Haskell's Maybe type
*/
#pragma once
#include <array>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <tuple>
#include <type_traits>
#include <utility>
namespace
Pistache
{
template
<
typename
T
>
class
Optional
;
namespace
types
{
template
<
typename
T
>
class
Some
{
public:
template
<
typename
U
>
friend
class
Pistache
::
Optional
;
explicit
Some
(
const
T
&
val
)
:
val_
(
val
)
{
}
explicit
Some
(
T
&&
val
)
:
val_
(
std
::
move
(
val
))
{
}
private:
T
val_
;
};
class
None
{
};
namespace
impl
{
template
<
typename
Func
>
struct
callable_trait
:
public
callable_trait
<
decltype
(
&
Func
::
operator
())
>
{
};
template
<
typename
Class
,
typename
Ret
,
typename
...
Args
>
struct
callable_trait
<
Ret
(
Class
::*
)(
Args
...)
const
>
{
static
constexpr
size_t
Arity
=
sizeof
...(
Args
);
typedef
std
::
tuple
<
Args
...
>
ArgsType
;
typedef
Ret
ReturnType
;
template
<
size_t
Index
>
struct
Arg
{
static_assert
(
Index
<
Arity
,
"Invalid index"
);
typedef
typename
std
::
tuple_element
<
Index
,
ArgsType
>::
type
Type
;
};
};
}
// namespace impl
template
<
typename
Func
,
bool
IsBindExp
=
std
::
is_bind_expression
<
Func
>
::
value
>
struct
callable_trait
;
/* std::bind returns an unspecified type which contains several overloads
* of operator(). Thus, decltype(&operator()) does not compile since operator()
* is overloaded. To bypass that, we only define the ReturnType for bind
* expressions
*/
template
<
typename
Func
>
struct
callable_trait
<
Func
,
true
>
{
typedef
typename
Func
::
result_type
ReturnType
;
};
template
<
typename
Func
>
struct
callable_trait
<
Func
,
false
>
:
public
impl
::
callable_trait
<
Func
>
{
};
template
<
typename
T
>
struct
is_nothrow_move_constructible
:
std
::
is_nothrow_constructible
<
T
,
typename
std
::
add_rvalue_reference
<
T
>::
type
>
{
};
template
<
class
T
>
struct
is_move_constructible
:
std
::
is_constructible
<
T
,
typename
std
::
add_rvalue_reference
<
T
>::
type
>
{
};
// Workaround for C++14 defect (CWG 1558)
template
<
typename
...
Ts
>
struct
make_void
{
typedef
void
type
;
};
template
<
typename
...
Ts
>
using
void_t
=
typename
make_void
<
Ts
...
>::
type
;
// cppcheck 1.88 (and earlier?) are unable to handle the following template.
// cppcheck reports:
// (error) Syntax Error: AST broken, binary operator '>' doesn't have two
// operands.
// In order to run cppcheck on the rest of this file, we need to cause cppcheck
// to skip the next few lines of code (the code is valid and compiles just
// fine).
#ifndef CPPCHECK
template
<
typename
,
typename
=
void_t
<
>
>
struct
has_equalto_operator
:
std
::
false_type
{
};
#endif
template
<
typename
T
>
struct
has_equalto_operator
<
T
,
void_t
<
decltype
(
std
::
declval
<
T
>
()
==
std
::
declval
<
T
>
())
>>
:
std
::
true_type
{
};
}
// namespace types
inline
types
::
None
None
()
{
return
types
::
None
();
}
template
<
typename
T
,
typename
CleanT
=
typename
std
::
remove_reference
<
T
>
::
type
>
inline
types
::
Some
<
CleanT
>
Some
(
T
&&
value
)
{
return
types
::
Some
<
CleanT
>
(
std
::
forward
<
T
>
(
value
));
}
template
<
typename
T
>
class
Optional
{
public:
Optional
()
{
none_flag
=
NoneMarker
;
}
// TODO: SFINAE-out if T is not trivially_copyable
Optional
(
const
Optional
<
T
>&
other
)
{
if
(
!
other
.
isEmpty
())
{
::
new
(
data
())
T
(
*
other
.
data
());
none_flag
=
ValueMarker
;
}
else
{
none_flag
=
NoneMarker
;
}
}
Optional
(
Optional
<
T
>&&
other
)
noexcept
(
types
::
is_nothrow_move_constructible
<
T
>::
value
)
{
*
this
=
std
::
move
(
other
);
}
template
<
typename
U
>
Optional
(
types
::
Some
<
U
>
some
)
:
none_flag
(
NoneMarker
)
{
static_assert
(
std
::
is_same
<
T
,
U
>::
value
||
std
::
is_convertible
<
U
,
T
>::
value
,
"Types mismatch"
);
from_some_helper
(
std
::
move
(
some
),
types
::
is_move_constructible
<
U
>
());
}
Optional
(
types
::
None
)
{
none_flag
=
NoneMarker
;
}
template
<
typename
U
>
Optional
<
T
>&
operator
=
(
types
::
Some
<
U
>
some
)
{
static_assert
(
std
::
is_same
<
T
,
U
>::
value
||
std
::
is_convertible
<
U
,
T
>::
value
,
"Types mismatch"
);
if
(
none_flag
!=
NoneMarker
)
{
data
()
->~
T
();
}
from_some_helper
(
std
::
move
(
some
),
types
::
is_move_constructible
<
U
>
());
return
*
this
;
}
Optional
<
T
>&
operator
=
(
types
::
None
)
{
if
(
none_flag
!=
NoneMarker
)
{
data
()
->~
T
();
}
none_flag
=
NoneMarker
;
return
*
this
;
}
// TODO: SFINAE-out if T is not trivially_copyable
Optional
<
T
>&
operator
=
(
const
Optional
<
T
>&
other
)
{
if
(
!
other
.
isEmpty
())
{
if
(
none_flag
!=
NoneMarker
)
{
data
()
->~
T
();
}
::
new
(
data
())
T
(
*
other
.
data
());
none_flag
=
ValueMarker
;
}
else
{
if
(
none_flag
!=
NoneMarker
)
{
data
()
->~
T
();
}
none_flag
=
NoneMarker
;
}
return
*
this
;
}
Optional
<
T
>&
operator
=
(
Optional
<
T
>&&
other
)
noexcept
(
types
::
is_nothrow_move_constructible
<
T
>::
value
)
{
if
(
!
other
.
isEmpty
())
{
move_helper
(
std
::
move
(
other
),
types
::
is_move_constructible
<
T
>
());
other
.
none_flag
=
NoneMarker
;
}
else
{
none_flag
=
NoneMarker
;
}
return
*
this
;
}
bool
isEmpty
()
const
{
return
none_flag
==
NoneMarker
;
}
T
getOrElse
(
const
T
&
defaultValue
)
{
if
(
none_flag
!=
NoneMarker
)
{
return
*
constData
();
}
return
defaultValue
;
}
const
T
&
getOrElse
(
const
T
&
defaultValue
)
const
{
if
(
none_flag
!=
NoneMarker
)
{
return
*
constData
();
}
return
defaultValue
;
}
template
<
typename
Func
>
void
orElse
(
Func
func
)
const
{
if
(
isEmpty
())
{
func
();
}
}
T
get
()
{
return
*
constData
();
}
const
T
&
get
()
const
{
return
*
constData
();
}
T
&
unsafeGet
()
const
{
return
*
data
();
}
~
Optional
()
{
if
(
!
isEmpty
())
{
data
()
->~
T
();
}
}
bool
operator
==
(
const
Optional
<
T
>&
other
)
const
{
static_assert
(
types
::
has_equalto_operator
<
T
>::
value
,
"optional<T> requires T to be comparable by equal to operator"
);
return
(
isEmpty
()
&&
other
.
isEmpty
())
||
(
!
isEmpty
()
&&
!
other
.
isEmpty
()
&&
get
()
==
other
.
get
());
}
bool
operator
!=
(
const
Optional
<
T
>&
other
)
const
{
static_assert
(
types
::
has_equalto_operator
<
T
>::
value
,
"optional<T> requires T to be comparable by equal to operator"
);
return
!
(
*
this
==
other
);
}
private:
T
*
constData
()
const
{
return
const_cast
<
T
*
const
>
(
reinterpret_cast
<
const
T
*
const
>
(
bytes
.
data
()));
}
T
*
data
()
const
{
return
const_cast
<
T
*>
(
reinterpret_cast
<
const
T
*>
(
bytes
.
data
()));
}
void
move_helper
(
Optional
<
T
>&&
other
,
std
::
true_type
)
{
::
new
(
data
())
T
(
std
::
move
(
*
other
.
data
()));
none_flag
=
ValueMarker
;
}
void
move_helper
(
Optional
<
T
>&&
other
,
std
::
false_type
)
{
::
new
(
data
())
T
(
*
other
.
data
());
none_flag
=
ValueMarker
;
}
template
<
typename
U
>
void
from_some_helper
(
types
::
Some
<
U
>
some
,
std
::
true_type
)
{
::
new
(
data
())
T
(
std
::
move
(
some
.
val_
));
none_flag
=
ValueMarker
;
}
template
<
typename
U
>
void
from_some_helper
(
types
::
Some
<
U
>
some
,
std
::
false_type
)
{
::
new
(
data
())
T
(
some
.
val_
);
none_flag
=
ValueMarker
;
}
typedef
uint8_t
none_flag_t
;
static
constexpr
none_flag_t
NoneMarker
=
1
;
static
constexpr
none_flag_t
ValueMarker
=
0
;
alignas
(
T
)
std
::
array
<
uint8_t
,
sizeof
(
T
)
>
bytes
;
none_flag_t
none_flag
;
};
#define PistacheCheckSize(Type) \
static_assert(sizeof(Optional<Type>) == sizeof(Type) + alignof(Type), \
"Size differs")
PistacheCheckSize
(
uint8_t
);
PistacheCheckSize
(
uint16_t
);
PistacheCheckSize
(
int
);
PistacheCheckSize
(
void
*
);
PistacheCheckSize
(
std
::
string
);
namespace
details
{
template
<
typename
T
>
struct
RemoveOptional
{
typedef
T
Type
;
};
template
<
typename
T
>
struct
RemoveOptional
<
Optional
<
T
>>
{
typedef
T
Type
;
};
template
<
typename
T
,
typename
Func
>
void
do_static_checks
(
std
::
false_type
)
{
static_assert
(
types
::
callable_trait
<
Func
>::
Arity
==
1
,
"The function must take exactly 1 argument"
);
typedef
typename
types
::
callable_trait
<
Func
>::
template
Arg
<
0
>
::
Type
ArgType
;
typedef
typename
std
::
remove_cv
<
typename
std
::
remove_reference
<
ArgType
>::
type
>::
type
CleanArgType
;
static_assert
(
std
::
is_same
<
CleanArgType
,
T
>::
value
||
std
::
is_convertible
<
CleanArgType
,
T
>::
value
,
"Function parameter type mismatch"
);
}
template
<
typename
T
,
typename
Func
>
void
do_static_checks
(
std
::
true_type
)
{
}
template
<
typename
T
,
typename
Func
>
void
static_checks
()
{
do_static_checks
<
T
,
Func
>
(
std
::
is_bind_expression
<
Func
>
());
}
template
<
typename
Func
>
struct
IsArgMovable
:
public
IsArgMovable
<
decltype
(
&
Func
::
operator
())
>
{
};
template
<
typename
R
,
typename
Class
,
typename
Arg
>
struct
IsArgMovable
<
R
(
Class
::*
)(
Arg
)
const
>
:
public
std
::
is_rvalue_reference
<
Arg
>
{
};
template
<
typename
Func
,
typename
Arg
>
typename
std
::
conditional
<
IsArgMovable
<
Func
>::
value
,
Arg
&&
,
const
Arg
&>::
type
tryMove
(
Arg
&
arg
)
{
return
std
::
move
(
arg
);
}
}
// namespace details
template
<
typename
T
,
typename
Func
>
const
Optional
<
T
>&
optionally_do
(
const
Optional
<
T
>&
option
,
Func
func
)
{
details
::
static_checks
<
T
,
Func
>
();
static_assert
(
std
::
is_same
<
typename
types
::
callable_trait
<
Func
>::
ReturnType
,
void
>::
value
,
"Use optionally_map if you want to return a value"
);
if
(
!
option
.
isEmpty
())
{
func
(
details
::
tryMove
<
Func
>
(
option
.
unsafeGet
()));
}
return
option
;
}
template
<
typename
T
,
typename
Func
>
auto
optionally_map
(
const
Optional
<
T
>&
option
,
Func
func
)
->
Optional
<
typename
types
::
callable_trait
<
Func
>::
ReturnType
>
{
details
::
static_checks
<
T
,
Func
>
();
if
(
!
option
.
isEmpty
())
{
return
Some
(
func
(
details
::
tryMove
<
Func
>
(
option
.
unsafeGet
())));
}
return
None
();
}
template
<
typename
T
,
typename
Func
>
auto
optionally_fmap
(
const
Optional
<
T
>&
option
,
Func
func
)
->
Optional
<
typename
details
::
RemoveOptional
<
typename
types
::
callable_trait
<
Func
>::
ReturnType
>::
Type
>
{
details
::
static_checks
<
T
,
Func
>
();
if
(
!
option
.
isEmpty
())
{
const
auto
&
ret
=
func
(
details
::
tryMove
<
Func
>
(
option
.
unsafeGet
()));
if
(
!
ret
.
isEmpty
())
{
return
Some
(
ret
.
get
());
}
}
return
None
();
}
template
<
typename
T
,
typename
Func
>
Optional
<
T
>
optionally_filter
(
const
Optional
<
T
>&
option
,
Func
func
)
{
details
::
static_checks
<
T
,
Func
>
();
typedef
typename
types
::
callable_trait
<
Func
>::
ReturnType
ReturnType
;
static_assert
(
std
::
is_same
<
ReturnType
,
bool
>::
value
||
std
::
is_convertible
<
ReturnType
,
bool
>::
value
,
"The predicate must return a boolean value"
);
if
(
!
option
.
isEmpty
()
&&
func
(
option
.
get
()))
{
return
Some
(
option
.
get
());
}
return
None
();
}
}
// namespace Pistache
include/pistache/thirdparty/date.h
View file @
86ef2a43
include/pistache/transport.h
View file @
86ef2a43
...
...
@@ -8,7 +8,6 @@
#include <pistache/async.h>
#include <pistache/mailbox.h>
#include <pistache/optional.h>
#include <pistache/reactor.h>
#include <pistache/stream.h>
...
...
@@ -16,6 +15,7 @@
#include <deque>
#include <memory>
#include <mutex>
#include <optional>
#include <unordered_map>
namespace
Pistache
...
...
src/common/cookie.cc
View file @
86ef2a43
...
...
@@ -9,6 +9,7 @@
#include <pistache/stream.h>
#include <iterator>
#include <optional>
#include <unordered_map>
namespace
Pistache
...
...
@@ -38,21 +39,21 @@ namespace Pistache
struct
AttributeMatcher
;
template
<
>
struct
AttributeMatcher
<
O
ptional
<
std
::
string
>>
struct
AttributeMatcher
<
std
::
o
ptional
<
std
::
string
>>
{
static
void
match
(
StreamCursor
&
cursor
,
Cookie
*
obj
,
O
ptional
<
std
::
string
>
Cookie
::*
attr
)
std
::
o
ptional
<
std
::
string
>
Cookie
::*
attr
)
{
auto
token
=
matchValue
(
cursor
);
obj
->*
attr
=
Some
(
token
.
text
()
);
obj
->*
attr
=
token
.
text
(
);
}
};
template
<
>
struct
AttributeMatcher
<
O
ptional
<
int
>>
struct
AttributeMatcher
<
std
::
o
ptional
<
int
>>
{
static
void
match
(
StreamCursor
&
cursor
,
Cookie
*
obj
,
O
ptional
<
int
>
Cookie
::*
attr
)
std
::
o
ptional
<
int
>
Cookie
::*
attr
)
{
auto
token
=
matchValue
(
cursor
);
...
...
@@ -70,7 +71,7 @@ namespace Pistache
return
ret
;
};
obj
->*
attr
=
Some
(
strntol
(
token
.
rawText
(),
token
.
size
()
));
obj
->*
attr
=
strntol
(
token
.
rawText
(),
token
.
size
(
));
}
};
...
...
@@ -85,13 +86,13 @@ namespace Pistache
};
template
<
>
struct
AttributeMatcher
<
O
ptional
<
FullDate
>>
struct
AttributeMatcher
<
std
::
o
ptional
<
FullDate
>>
{
static
void
match
(
StreamCursor
&
cursor
,
Cookie
*
obj
,
O
ptional
<
FullDate
>
Cookie
::*
attr
)
std
::
o
ptional
<
FullDate
>
Cookie
::*
attr
)
{
auto
token
=
matchValue
(
cursor
);
obj
->*
attr
=
Some
(
FullDate
::
fromString
(
token
.
text
()
));
obj
->*
attr
=
FullDate
::
fromString
(
token
.
text
(
));
}
};
...
...
@@ -202,23 +203,31 @@ namespace Pistache
void
Cookie
::
write
(
std
::
ostream
&
os
)
const
{
os
<<
name
<<
"="
<<
value
;
optionally_do
(
path
,
[
&
](
const
std
::
string
&
value
)
{
if
(
path
.
has_value
())
{
const
std
::
string
&
value
=
*
path
;
os
<<
"; "
;
os
<<
"Path="
<<
value
;
});
optionally_do
(
domain
,
[
&
](
const
std
::
string
&
value
)
{
}
if
(
domain
.
has_value
())
{
const
std
::
string
&
value
=
*
domain
;
os
<<
"; "
;
os
<<
"Domain="
<<
value
;
});
optionally_do
(
maxAge
,
[
&
](
int
value
)
{
}
if
(
maxAge
.
has_value
())
{
int
value
=
*
maxAge
;
os
<<
"; "
;
os
<<
"Max-Age="
<<
value
;
});
optionally_do
(
expires
,
[
&
](
const
FullDate
&
value
)
{
}
if
(
expires
.
has_value
())
{
const
FullDate
&
value
=
*
expires
;
os
<<
"; "
;
os
<<
"Expires="
;
value
.
write
(
os
);
}
);
}
if
(
secure
)
os
<<
"; Secure"
;
if
(
httpOnly
)
...
...
src/common/description.cc
View file @
86ef2a43
...
...
@@ -158,7 +158,7 @@ namespace Pistache
return
it
->
second
;
}
O
ptional
<
Path
>
PathGroup
::
path
(
const
std
::
string
&
name
,
std
::
o
ptional
<
Path
>
PathGroup
::
path
(
const
std
::
string
&
name
,
Http
::
Method
method
)
const
{
auto
group
=
paths
(
name
);
...
...
@@ -167,9 +167,9 @@ namespace Pistache
if
(
it
!=
std
::
end
(
group
))
{
return
Optional
<
Path
>
(
Some
(
*
it
)
);
return
std
::
optional
<
Path
>
(
*
it
);
}
return
Optional
<
Path
>
(
None
())
;
return
std
::
nullopt
;
}
PathGroup
::
group_iterator
PathGroup
::
add
(
Path
path
)
...
...
@@ -258,13 +258,13 @@ namespace Pistache
InfoBuilder
&
InfoBuilder
::
contact
(
std
::
string
name
,
std
::
string
url
,
std
::
string
email
)
{
info_
->
contact
=
Some
(
Contact
(
std
::
move
(
name
),
std
::
move
(
url
),
std
::
move
(
email
)
));
info_
->
contact
=
Contact
(
std
::
move
(
name
),
std
::
move
(
url
),
std
::
move
(
email
));
return
*
this
;
}
InfoBuilder
&
InfoBuilder
::
license
(
std
::
string
name
,
std
::
string
url
)
{
info_
->
license
=
Some
(
License
(
std
::
move
(
name
),
std
::
move
(
url
)
));
info_
->
license
=
License
(
std
::
move
(
name
),
std
::
move
(
url
));
return
*
this
;
}
...
...
src/common/http.cc
View file @
86ef2a43
...
...
@@ -586,13 +586,13 @@ namespace Pistache
params
.
insert
(
std
::
make_pair
(
std
::
move
(
name
),
std
::
move
(
value
)));
}
O
ptional
<
std
::
string
>
Query
::
get
(
const
std
::
string
&
name
)
const
std
::
o
ptional
<
std
::
string
>
Query
::
get
(
const
std
::
string
&
name
)
const
{
auto
it
=
params
.
find
(
name
);
if
(
it
==
std
::
end
(
params
))
return
Optional
<
std
::
string
>
(
None
())
;
return
std
::
nullopt
;
return
Optional
<
std
::
string
>
(
Some
(
it
->
second
)
);
return
std
::
optional
<
std
::
string
>
(
it
->
second
);
}
std
::
string
Query
::
as_str
()
const
...
...
src/common/http_headers.cc
View file @
86ef2a43
...
...
@@ -170,15 +170,15 @@ namespace Pistache
return
header
.
second
;
}
O
ptional
<
Raw
>
Collection
::
tryGetRaw
(
const
std
::
string
&
name
)
const
std
::
o
ptional
<
Raw
>
Collection
::
tryGetRaw
(
const
std
::
string
&
name
)
const
{
auto
it
=
rawHeaders
.
find
(
name
);
if
(
it
==
std
::
end
(
rawHeaders
))
{
return
Optional
<
Raw
>
(
None
())
;
return
std
::
nullopt
;
}
return
Optional
<
Raw
>
(
Some
(
it
->
second
)
);
return
std
::
optional
<
Raw
>
(
it
->
second
);
}
bool
Collection
::
has
(
const
std
::
string
&
name
)
const
...
...
src/common/mime.cc
View file @
86ef2a43
...
...
@@ -240,7 +240,7 @@ namespace Pistache
double
val
;
if
(
!
match_double
(
&
val
,
cursor
))
raise
(
"Invalid quality factor"
);
q_
=
Some
(
Q
::
fromFloat
(
val
)
);
q_
=
Q
::
fromFloat
(
val
);
}
else
{
...
...
@@ -266,17 +266,17 @@ namespace Pistache
}
}
void
MediaType
::
setQuality
(
Q
quality
)
{
q_
=
Some
(
quality
)
;
}
void
MediaType
::
setQuality
(
Q
quality
)
{
q_
=
quality
;
}
O
ptional
<
std
::
string
>
MediaType
::
getParam
(
const
std
::
string
&
name
)
const
std
::
o
ptional
<
std
::
string
>
MediaType
::
getParam
(
const
std
::
string
&
name
)
const
{
auto
it
=
params
.
find
(
name
);
if
(
it
==
std
::
end
(
params
))
{
return
Optional
<
std
::
string
>
(
None
())
;
return
std
::
nullopt
;
}
return
Optional
<
std
::
string
>
(
Some
(
it
->
second
)
);
return
std
::
optional
<
std
::
string
>
(
it
->
second
);
}
void
MediaType
::
setParam
(
const
std
::
string
&
name
,
std
::
string
value
)
...
...
@@ -339,10 +339,12 @@ namespace Pistache
res
+=
suffixString
(
suffix_
);
}
optionally_do
(
q_
,
[
&
res
](
Q
quality
)
{
if
(
q_
.
has_value
())
{
Q
quality
=
*
q_
;
res
+=
"; "
;
res
+=
quality
.
toString
();
}
);
}
for
(
const
auto
&
param
:
params
)
{
...
...
tests/CMakeLists.txt
View file @
86ef2a43
...
...
@@ -36,7 +36,6 @@ pistache_test(mailbox_test)
pistache_test
(
stream_test
)
pistache_test
(
reactor_test
)
pistache_test
(
threadname_test
)
pistache_test
(
optional_test
)
pistache_test
(
log_api_test
)
pistache_test
(
string_logger_test
)
...
...
tests/cookie_test.cc
View file @
86ef2a43
...
...
@@ -28,29 +28,29 @@ TEST(cookie_test, attributes_test)
parse
(
"SID=31d4d96e407aad42; Path=/"
,
[](
const
Cookie
&
c
)
{
ASSERT_EQ
(
c
.
name
,
"SID"
);
ASSERT_EQ
(
c
.
value
,
"31d4d96e407aad42"
);
ASSERT_EQ
(
c
.
path
.
getOrElse
(
""
),
"/"
);
ASSERT_EQ
(
c
.
path
.
value_or
(
""
),
"/"
);
});
parse
(
"SID=31d4d96e407aad42; Path=/; Domain=example.com"
,
[](
const
Cookie
&
c
)
{
ASSERT_EQ
(
c
.
path
.
getOrElse
(
""
),
"/"
);
ASSERT_EQ
(
c
.
domain
.
getOrElse
(
""
),
"example.com"
);
ASSERT_EQ
(
c
.
path
.
value_or
(
""
),
"/"
);
ASSERT_EQ
(
c
.
domain
.
value_or
(
""
),
"example.com"
);
});
parse
(
"lang=en-US; Path=/; Domain=example.com; Max-Age=10"
,
[](
const
Cookie
&
c
)
{
ASSERT_EQ
(
c
.
name
,
"lang"
);
ASSERT_EQ
(
c
.
value
,
"en-US"
);
ASSERT_EQ
(
c
.
path
.
getOrElse
(
""
),
"/"
);
ASSERT_EQ
(
c
.
domain
.
getOrElse
(
""
),
"example.com"
);
ASSERT_EQ
(
c
.
maxAge
.
getOrElse
(
0
),
10
);
ASSERT_EQ
(
c
.
path
.
value_or
(
""
),
"/"
);
ASSERT_EQ
(
c
.
domain
.
value_or
(
""
),
"example.com"
);
ASSERT_EQ
(
c
.
maxAge
.
value_or
(
0
),
10
);
});
parse
(
"lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT"
,
[](
const
Cookie
&
c
)
{
ASSERT_EQ
(
c
.
name
,
"lang"
);
ASSERT_EQ
(
c
.
value
,
"en-US"
);
auto
expires
=
c
.
expires
.
getOrElse
(
FullDate
());
auto
expires
=
c
.
expires
.
value_or
(
FullDate
());
auto
date
=
expires
.
date
();
using
namespace
std
::
chrono
;
...
...
@@ -61,7 +61,7 @@ TEST(cookie_test, attributes_test)
parse
(
"lang=en-US; Path=/; Domain=example.com;"
,
[](
const
Cookie
&
c
)
{
ASSERT_EQ
(
c
.
name
,
"lang"
);
ASSERT_EQ
(
c
.
value
,
"en-US"
);
ASSERT_EQ
(
c
.
domain
.
getOrElse
(
""
),
"example.com"
);
ASSERT_EQ
(
c
.
domain
.
value_or
(
""
),
"example.com"
);
});
}
...
...
@@ -70,7 +70,7 @@ TEST(cookie_test, bool_test)
parse
(
"SID=31d4d96e407aad42; Path=/; Secure"
,
[](
const
Cookie
&
c
)
{
ASSERT_EQ
(
c
.
name
,
"SID"
);
ASSERT_EQ
(
c
.
value
,
"31d4d96e407aad42"
);
ASSERT_EQ
(
c
.
path
.
getOrElse
(
""
),
"/"
);
ASSERT_EQ
(
c
.
path
.
value_or
(
""
),
"/"
);
ASSERT_TRUE
(
c
.
secure
);
ASSERT_FALSE
(
c
.
httpOnly
);
});
...
...
@@ -78,7 +78,7 @@ TEST(cookie_test, bool_test)
parse
(
"SID=31d4d96e407aad42; Path=/; Secure; HttpOnly"
,
[](
const
Cookie
&
c
)
{
ASSERT_EQ
(
c
.
name
,
"SID"
);
ASSERT_EQ
(
c
.
value
,
"31d4d96e407aad42"
);
ASSERT_EQ
(
c
.
path
.
getOrElse
(
""
),
"/"
);
ASSERT_EQ
(
c
.
path
.
value_or
(
""
),
"/"
);
ASSERT_TRUE
(
c
.
secure
);
ASSERT_TRUE
(
c
.
httpOnly
);
});
...
...
@@ -89,7 +89,7 @@ TEST(cookie_test, ext_test)
parse
(
"lang=en-US; Path=/; Scope=Private"
,
[](
const
Cookie
&
c
)
{
ASSERT_EQ
(
c
.
name
,
"lang"
);
ASSERT_EQ
(
c
.
value
,
"en-US"
);
ASSERT_EQ
(
c
.
path
.
getOrElse
(
""
),
"/"
);
ASSERT_EQ
(
c
.
path
.
value_or
(
""
),
"/"
);
auto
fooIt
=
c
.
ext
.
find
(
"Scope"
);
ASSERT_TRUE
(
fooIt
!=
std
::
end
(
c
.
ext
));
ASSERT_EQ
(
fooIt
->
second
,
"Private"
);
...
...
@@ -99,8 +99,8 @@ TEST(cookie_test, ext_test)
TEST
(
cookie_test
,
write_test
)
{
Cookie
c1
(
"lang"
,
"fr-FR"
);
c1
.
path
=
Some
(
std
::
string
(
"/"
)
);
c1
.
domain
=
Some
(
std
::
string
(
"example.com"
)
);
c1
.
path
=
std
::
string
(
"/"
);
c1
.
domain
=
std
::
string
(
"example.com"
);
std
::
ostringstream
oss
;
oss
<<
c1
;
...
...
@@ -112,8 +112,8 @@ TEST(cookie_test, write_test)
FullDate
::
time_point
expires
=
date
::
sys_days
(
date
::
year
{
118
}
/
2
/
16
)
+
hours
(
17
);
c2
.
path
=
Some
(
std
::
string
(
"/"
)
);
c2
.
expires
=
Some
(
FullDate
(
expires
)
);
c2
.
path
=
std
::
string
(
"/"
);
c2
.
expires
=
FullDate
(
expires
);
oss
.
str
(
""
);
oss
<<
c2
;
...
...
tests/headers_test.cc
View file @
86ef2a43
...
...
@@ -18,7 +18,7 @@ TEST(headers_test, accept)
const
auto
&
mime
=
media
[
0
];
ASSERT_TRUE
(
mime
==
MIME
(
Audio
,
Star
));
ASSERT_TRUE
(
mime
.
q
().
getOrElse
(
Pistache
::
Http
::
Mime
::
Q
(
0
))
==
Pistache
::
Http
::
Mime
::
Q
(
20
));
ASSERT_TRUE
(
mime
.
q
().
value_or
(
Pistache
::
Http
::
Mime
::
Q
(
0
))
==
Pistache
::
Http
::
Mime
::
Q
(
20
));
}
Pistache
::
Http
::
Header
::
Accept
a2
;
...
...
@@ -35,7 +35,7 @@ TEST(headers_test, accept)
const
auto
&
m3
=
media
[
2
];
ASSERT_TRUE
(
m3
==
MIME
(
Text
,
Html
));
auto
level
=
m3
.
getParam
(
"level"
);
ASSERT_TRUE
(
level
.
getOrElse
(
""
)
==
"1"
);
ASSERT_TRUE
(
level
.
value_or
(
""
)
==
"1"
);
const
auto
&
m4
=
media
[
3
];
ASSERT_TRUE
(
m4
==
MIME
(
Star
,
Star
));
}
...
...
@@ -49,13 +49,13 @@ TEST(headers_test, accept)
ASSERT_TRUE
(
media
.
size
()
==
5U
);
ASSERT_TRUE
(
media
[
0
]
==
MIME
(
Text
,
Star
));
ASSERT_TRUE
(
media
[
0
].
q
().
getOrElse
(
Pistache
::
Http
::
Mime
::
Q
(
0
))
==
Pistache
::
Http
::
Mime
::
Q
(
30
));
ASSERT_TRUE
(
media
[
0
].
q
().
value_or
(
Pistache
::
Http
::
Mime
::
Q
(
0
))
==
Pistache
::
Http
::
Mime
::
Q
(
30
));
ASSERT_TRUE
(
media
[
1
]
==
MIME
(
Text
,
Html
));
ASSERT_TRUE
(
media
[
2
]
==
MIME
(
Text
,
Html
));
ASSERT_TRUE
(
media
[
3
]
==
MIME
(
Text
,
Html
));
ASSERT_TRUE
(
media
[
4
]
==
MIME
(
Star
,
Star
));
ASSERT_TRUE
(
media
[
4
].
q
().
getOrElse
(
Pistache
::
Http
::
Mime
::
Q
(
0
))
==
Pistache
::
Http
::
Mime
::
Q
::
fromFloat
(
0.5
));
ASSERT_TRUE
(
media
[
4
].
q
().
value_or
(
Pistache
::
Http
::
Mime
::
Q
(
0
))
==
Pistache
::
Http
::
Mime
::
Q
::
fromFloat
(
0.5
));
}
Pistache
::
Http
::
Header
::
Accept
a4
;
...
...
@@ -574,7 +574,7 @@ TEST(headers_test, content_type)
ASSERT_TRUE
(
"text/html; charset=ISO-8859-4"
==
oss
.
str
());
const
auto
&
mime
=
ct
.
mime
();
ASSERT_TRUE
(
mime
==
MIME
(
Text
,
Html
));
ASSERT_TRUE
(
mime
.
getParam
(
"charset"
).
getOrElse
(
""
)
==
"ISO-8859-4"
);
ASSERT_TRUE
(
mime
.
getParam
(
"charset"
).
value_or
(
""
)
==
"ISO-8859-4"
);
}
TEST
(
headers_test
,
access_control_allow_origin_test
)
...
...
@@ -821,10 +821,10 @@ TEST(headers_test, raw_headers_are_case_insensitive)
step
.
apply
(
cursor
);
// or the header you try and get, it should work:
ASSERT_FALSE
(
request
.
headers
().
tryGetRaw
(
"Custom-Header"
).
isEmpty
());
ASSERT_FALSE
(
request
.
headers
().
tryGetRaw
(
"CUSTOM-HEADER"
).
isEmpty
());
ASSERT_FALSE
(
request
.
headers
().
tryGetRaw
(
"custom-header"
).
isEmpty
());
ASSERT_FALSE
(
request
.
headers
().
tryGetRaw
(
"CuStOm-HeAdEr"
).
isEmpty
());
ASSERT_FALSE
(
request
.
headers
().
tryGetRaw
(
"Custom-Header"
).
has_value
());
ASSERT_FALSE
(
request
.
headers
().
tryGetRaw
(
"CUSTOM-HEADER"
).
has_value
());
ASSERT_FALSE
(
request
.
headers
().
tryGetRaw
(
"custom-header"
).
has_value
());
ASSERT_FALSE
(
request
.
headers
().
tryGetRaw
(
"CuStOm-HeAdEr"
).
has_value
());
}
}
...
...
tests/http_client_test.cc
View file @
86ef2a43
...
...
@@ -489,7 +489,7 @@ TEST(http_client_test, client_sends_query)
for
(
auto
entry
:
results
)
{
ASSERT_TRUE
(
query
.
has
(
entry
.
first
));
EXPECT_EQ
(
entry
.
second
,
query
.
get
(
entry
.
first
).
get
());
EXPECT_EQ
(
entry
.
second
,
query
.
get
(
entry
.
first
).
value
());
}
}
...
...
tests/mime_test.cc
View file @
86ef2a43
...
...
@@ -21,9 +21,9 @@ TEST(mime_test, basic_test)
ASSERT_TRUE
(
m2
.
toString
()
==
"application/xhtml+xml"
);
auto
m3
=
MIME
(
Text
,
Plain
);
ASSERT_TRUE
(
m3
.
q
().
isEmpty
());
ASSERT_TRUE
(
m3
.
q
().
has_value
());
m3
.
setQuality
(
Q
::
fromFloat
(
0.7
));
ASSERT_TRUE
(
m3
.
q
().
getOrElse
(
Q
(
0
))
==
Q
(
70
));
ASSERT_TRUE
(
m3
.
q
().
value_or
(
Q
(
0
))
==
Q
(
70
));
ASSERT_TRUE
(
m3
.
toString
()
==
"text/plain; q=0.7"
);
...
...
@@ -54,28 +54,28 @@ TEST(mime_test, valid_parsing_test)
{
parse
(
"application/json"
,
[](
const
MediaType
&
m1
)
{
ASSERT_TRUE
(
m1
==
MIME
(
Application
,
Json
));
ASSERT_TRUE
(
m1
.
q
().
isEmpty
());
ASSERT_TRUE
(
m1
.
q
().
has_value
());
});
parse
(
"application/xhtml+xml"
,
[](
const
MediaType
&
m2
)
{
ASSERT_TRUE
(
m2
==
MediaType
(
Type
::
Application
,
Subtype
::
Xhtml
,
Suffix
::
Xml
));
ASSERT_TRUE
(
m2
.
q
().
isEmpty
());
ASSERT_TRUE
(
m2
.
q
().
has_value
());
});
parse
(
"application/json; q=0.3"
,
[](
const
MediaType
&
m3
)
{
ASSERT_TRUE
(
m3
==
MIME
(
Application
,
Json
));
ASSERT_TRUE
(
m3
.
q
().
getOrElse
(
Q
(
0
))
==
Q
::
fromFloat
(
0.3
));
ASSERT_TRUE
(
m3
.
q
().
value_or
(
Q
(
0
))
==
Q
::
fromFloat
(
0.3
));
});
parse
(
"application/xhtml+xml; q=0.7"
,
[](
const
MediaType
&
m4
)
{
ASSERT_TRUE
(
m4
.
top
()
==
Type
::
Application
);
ASSERT_TRUE
(
m4
.
sub
()
==
Subtype
::
Xhtml
);
ASSERT_TRUE
(
m4
.
suffix
()
==
Suffix
::
Xml
);
ASSERT_TRUE
(
m4
.
q
().
getOrElse
(
Q
(
0
))
==
Q
(
70
));
ASSERT_TRUE
(
m4
.
q
().
value_or
(
Q
(
0
))
==
Q
(
70
));
});
parse
(
"application/xhtml+xml; q=0.78"
,
[](
const
MediaType
&
m5
)
{
ASSERT_TRUE
(
m5
.
q
().
getOrElse
(
Q
(
0
))
==
Q
(
78
));
ASSERT_TRUE
(
m5
.
q
().
value_or
(
Q
(
0
))
==
Q
(
78
));
});
parse
(
"application/vnd.adobe.flash-movie"
,
[](
const
MediaType
&
m6
)
{
...
...
@@ -108,15 +108,15 @@ TEST(mime_test, valid_parsing_test)
parse
(
"text/html; charset=ISO-8859-4"
,
[](
const
MediaType
&
m10
)
{
ASSERT_TRUE
(
m10
==
MIME
(
Text
,
Html
));
ASSERT_TRUE
(
m10
.
q
().
isEmpty
());
ASSERT_TRUE
(
m10
.
q
().
has_value
());
auto
charset
=
m10
.
getParam
(
"charset"
);
ASSERT_TRUE
(
charset
.
getOrElse
(
""
)
==
"ISO-8859-4"
);
ASSERT_TRUE
(
charset
.
value_or
(
""
)
==
"ISO-8859-4"
);
});
parse
(
"text/html; q=0.83; charset=ISO-8859-4"
,
[](
const
MediaType
&
m11
)
{
ASSERT_TRUE
(
m11
==
MIME
(
Text
,
Html
));
ASSERT_TRUE
(
m11
.
q
().
getOrElse
(
Q
(
0
))
==
Q
(
83
));
ASSERT_TRUE
(
m11
.
getParam
(
"charset"
).
getOrElse
(
""
)
==
"ISO-8859-4"
);
ASSERT_TRUE
(
m11
.
q
().
value_or
(
Q
(
0
))
==
Q
(
83
));
ASSERT_TRUE
(
m11
.
getParam
(
"charset"
).
value_or
(
""
)
==
"ISO-8859-4"
);
});
}
...
...
@@ -150,15 +150,15 @@ TEST(mime_test, should_parse_case_insensitive_issue_179)
{
parse
(
"Application/Json"
,
[](
const
Mime
::
MediaType
&
mime
)
{
ASSERT_TRUE
(
mime
==
MIME
(
Application
,
Json
));
ASSERT_TRUE
(
mime
.
q
().
isEmpty
());
ASSERT_TRUE
(
mime
.
q
().
has_value
());
});
parse
(
"aPpliCAtion/Xhtml+XML"
,
[](
const
MediaType
&
mime
)
{
ASSERT_TRUE
(
mime
==
MediaType
(
Type
::
Application
,
Subtype
::
Xhtml
,
Suffix
::
Xml
));
ASSERT_TRUE
(
mime
.
q
().
isEmpty
());
ASSERT_TRUE
(
mime
.
q
().
has_value
());
});
parse
(
"Application/Xhtml+XML; q=0.78"
,
[](
const
MediaType
&
mime
)
{
ASSERT_TRUE
(
mime
.
q
().
getOrElse
(
Q
(
0
))
==
Q
(
78
));
ASSERT_TRUE
(
mime
.
q
().
value_or
(
Q
(
0
))
==
Q
(
78
));
});
}
tests/optional_test.cc
deleted
100644 → 0
View file @
5b5e374d
#include "gtest/gtest.h"
#include <pistache/optional.h>
using
Pistache
::
Optional
;
TEST
(
optional
,
constructor
)
{
Optional
<
bool
>
value
(
Pistache
::
Some
(
true
));
ASSERT_FALSE
(
value
.
isEmpty
());
EXPECT_TRUE
(
value
.
get
());
}
TEST
(
optional
,
copy_constructor
)
{
Optional
<
bool
>
value
(
Pistache
::
Some
(
true
));
ASSERT_FALSE
(
value
.
isEmpty
());
EXPECT_TRUE
(
value
.
get
());
Optional
<
bool
>
copy_constructed
(
value
);
ASSERT_FALSE
(
copy_constructed
.
isEmpty
());
EXPECT_TRUE
(
copy_constructed
.
get
());
}
TEST
(
optional
,
copy_assignment_operator
)
{
Optional
<
bool
>
value
(
Pistache
::
Some
(
true
));
ASSERT_FALSE
(
value
.
isEmpty
());
Optional
<
bool
>
other
;
EXPECT_TRUE
(
other
.
isEmpty
());
other
=
value
;
ASSERT_FALSE
(
other
.
isEmpty
());
EXPECT_TRUE
(
other
.
get
());
}
TEST
(
optional
,
copy_assignment_operator_for_convertible_type
)
{
Optional
<
bool
>
value
;
EXPECT_TRUE
(
value
.
isEmpty
());
value
=
Pistache
::
Some
(
true
);
ASSERT_FALSE
(
value
.
isEmpty
());
EXPECT_TRUE
(
value
.
get
());
}
TEST
(
optional
,
copy_assignment_operator_for_self_assignment
)
{
Optional
<
bool
>
value
(
Pistache
::
Some
(
true
));
ASSERT_FALSE
(
value
.
isEmpty
());
EXPECT_TRUE
(
value
.
get
());
value
=
value
;
ASSERT_FALSE
(
value
.
isEmpty
());
EXPECT_TRUE
(
value
.
get
());
}
TEST
(
optional
,
move_constructor
)
{
Optional
<
bool
>
value
(
Pistache
::
Some
(
true
));
ASSERT_FALSE
(
value
.
isEmpty
());
EXPECT_TRUE
(
value
.
get
());
Optional
<
bool
>
value_from_move
(
std
::
move
(
value
));
ASSERT_FALSE
(
value_from_move
.
isEmpty
());
EXPECT_TRUE
(
value_from_move
.
get
());
}
TEST
(
optional
,
move_assignment_operator
)
{
Optional
<
bool
>
value
(
Pistache
::
Some
(
true
));
ASSERT_FALSE
(
value
.
isEmpty
());
EXPECT_TRUE
(
value
.
get
());
Optional
<
bool
>
move_assigned
;
move_assigned
=
std
::
move
(
value
);
ASSERT_FALSE
(
move_assigned
.
isEmpty
());
EXPECT_TRUE
(
move_assigned
.
get
());
}
TEST
(
optional
,
integer
)
{
Optional
<
int32_t
>
value
(
Pistache
::
Some
(
1
));
ASSERT_FALSE
(
value
.
isEmpty
());
EXPECT_TRUE
(
value
.
get
());
}
TEST
(
optional
,
constructor_none
)
{
Optional
<
bool
>
value
(
Pistache
::
None
());
EXPECT_TRUE
(
value
.
isEmpty
());
}
TEST
(
optional
,
copy_constructor_none
)
{
Optional
<
bool
>
value
(
Pistache
::
None
());
EXPECT_TRUE
(
value
.
isEmpty
());
Optional
<
bool
>
copy_constructed
(
value
);
EXPECT_TRUE
(
value
.
isEmpty
());
}
TEST
(
optional
,
copy_assignment_operator_none
)
{
Optional
<
bool
>
value
(
Pistache
::
None
());
EXPECT_TRUE
(
value
.
isEmpty
());
Optional
<
bool
>
assigned
=
Pistache
::
None
();
EXPECT_TRUE
(
assigned
.
isEmpty
());
}
TEST
(
optional
,
move_constructor_none
)
{
Optional
<
bool
>
value
(
Pistache
::
None
());
EXPECT_TRUE
(
value
.
isEmpty
());
Optional
<
bool
>
move_constructed
(
std
::
move
(
value
));
EXPECT_TRUE
(
move_constructed
.
isEmpty
());
}
TEST
(
optional
,
move_assignment_operator_none
)
{
Optional
<
bool
>
value
(
Pistache
::
None
());
EXPECT_TRUE
(
value
.
isEmpty
());
Optional
<
bool
>
move_assigned
(
std
::
move
(
value
));
EXPECT_TRUE
(
move_assigned
.
isEmpty
());
}
TEST
(
optional
,
integer_none
)
{
Optional
<
int32_t
>
value
(
Pistache
::
None
());
EXPECT_TRUE
(
value
.
isEmpty
());
}
TEST
(
optional
,
equal_operator_empty_equalto_empty
)
{
Optional
<
int32_t
>
value
(
Pistache
::
None
());
Optional
<
int32_t
>
value2
(
Pistache
::
None
());
EXPECT_EQ
(
value
,
value2
);
}
TEST
(
optional
,
equal_operator_value_equalto_value
)
{
Optional
<
int32_t
>
value
(
Pistache
::
Some
(
1
));
Optional
<
int32_t
>
value2
(
Pistache
::
Some
(
1
));
EXPECT_EQ
(
value
,
value2
);
}
TEST
(
optional
,
equal_operator_empty_notequalto_value
)
{
Optional
<
int32_t
>
value
(
Pistache
::
None
());
Optional
<
int32_t
>
value2
(
Pistache
::
Some
(
2
));
EXPECT_NE
(
value
,
value2
);
}
TEST
(
optional
,
equal_operator_value_notequalto_value
)
{
Optional
<
int32_t
>
value
(
Pistache
::
Some
(
1
));
Optional
<
int32_t
>
value2
(
Pistache
::
Some
(
2
));
EXPECT_NE
(
value
,
value2
);
}
struct
not_comparable
{
bool
operator
==
(
const
not_comparable
&
other
)
const
=
delete
;
};
TEST
(
has_equalto_operator
,
is_comparable_type
)
{
using
Pistache
::
types
::
has_equalto_operator
;
EXPECT_FALSE
(
has_equalto_operator
<
not_comparable
>::
value
);
EXPECT_TRUE
(
has_equalto_operator
<
int
>::
value
);
EXPECT_TRUE
(
has_equalto_operator
<
double
>::
value
);
EXPECT_TRUE
(
has_equalto_operator
<
std
::
string
>::
value
);
}
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