Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F386281
types.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
6 KB
Referenced Files
None
Subscribers
None
types.hpp
View Options
/*******************************************************************************
*
* File: types.hpp
*
* Contents: Implementation of some basic convenience types.
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
* This implementation is partially based on the implementation of
* corresponding parts of CAF.
* TODO: Check license.
*
******************************************************************************/
#ifndef ROSA_SUPPORT_TYPES_HPP
#define ROSA_SUPPORT_TYPES_HPP
#include
"rosa/support/debug.hpp"
#include
<string>
namespace
rosa
{
/* ************************************************************************** *
* Unit *
* ************************************************************************** */
// Unit is analogous to void, but can be safely returned, stored, etc.
// to enable higher-order abstraction without cluttering code with
// exceptions for void (which can't be stored, for example).
struct
UnitType
{
constexpr
UnitType
()
noexcept
{
// nop
}
constexpr
UnitType
(
const
UnitType
&
)
noexcept
{
// nop
}
template
<
class
T
>
explicit
constexpr
UnitType
(
T
&&
)
noexcept
{
// nop
}
template
<
class
...
Ts
>
constexpr
UnitType
operator
()(
Ts
&&
...)
const
noexcept
{
return
{};
}
};
using
unit_t
=
UnitType
;
static
constexpr
unit_t
unit
=
unit_t
{};
// NOLINT
inline
std
::
string
to_string
(
const
unit_t
&
)
{
return
"unit"
;
}
template
<
typename
T
>
struct
LiftVoid
{
using
Type
=
T
;
};
template
<>
struct
LiftVoid
<
void
>
{
using
Type
=
unit_t
;
};
template
<
typename
T
>
struct
UnliftVoid
{
using
Type
=
T
;
};
template
<>
struct
UnliftVoid
<
unit_t
>
{
using
Type
=
void
;
};
/* ************************************************************************** *
* None *
* ************************************************************************** */
// Represents "nothing", e.g., for clearing an Optional by assigning none.
struct
NoneType
{
constexpr
NoneType
()
{
// nop
}
constexpr
explicit
operator
bool
()
const
{
return
false
;
}
};
using
none_t
=
NoneType
;
static
constexpr
none_t
none
=
none_t
{};
// NOLINT
inline
std
::
string
to_string
(
const
none_t
&
)
{
return
"none"
;
}
/* ************************************************************************** *
* Optional *
* ************************************************************************** */
// A C++17 compatible optional implementation.
template
<
class
T
>
class
Optional
{
public
:
using
Type
=
T
;
// Creates an instance without value.
Optional
(
const
none_t
&
=
none
)
:
Valid
(
false
)
{
// nop
}
// Creates an valid instance from value.
template
<
class
U
,
class
E
=
typename
std
::
enable_if
<
std
::
is_convertible
<
U
,
T
>::
value
>::
type
>
Optional
(
U
X
)
:
Valid
(
false
)
{
cr
(
std
::
move
(
X
));
}
Optional
(
const
Optional
&
Other
)
:
Valid
(
false
)
{
if
(
Other
.
Valid
)
{
cr
(
Other
.
Value
);
}
}
Optional
(
Optional
&&
Other
)
noexcept
(
std
::
is_nothrow_move_constructible
<
T
>::
value
)
:
Valid
(
false
)
{
if
(
Other
.
Valid
)
{
cr
(
std
::
move
(
Other
.
Value
));
}
}
~
Optional
()
{
destroy
();
}
Optional
&
operator
=
(
const
Optional
&
Other
)
{
if
(
Valid
)
{
if
(
Other
.
Valid
)
{
Value
=
Other
.
Value
;
}
else
{
destroy
();
}
}
else
if
(
Other
.
Valid
)
{
cr
(
Other
.
Value
);
}
return
*
this
;
}
Optional
&
operator
=
(
Optional
&&
Other
)
noexcept
(
std
::
is_nothrow_destructible
<
T
>::
value
&&
std
::
is_nothrow_move_assignable
<
T
>::
value
)
{
if
(
Valid
)
{
if
(
Other
.
Valid
)
{
Value
=
std
::
move
(
Other
.
Value
);
}
else
{
destroy
();
}
}
else
if
(
Other
.
Valid
)
{
cr
(
std
::
move
(
Other
.
Value
));
}
return
*
this
;
}
// Checks whether this object contains a value.
explicit
operator
bool
()
const
{
return
Valid
;
}
// Checks whether this object does not contain a value.
bool
operator
!
()
const
{
return
!
Valid
;
}
// Returns the value.
// PRE: Valid
T
&
operator
*
()
{
ASSERT
(
Valid
);
return
Value
;
}
// Returns the value.
// PRE: Valid
const
T
&
operator
*
()
const
{
ASSERT
(
Valid
);
return
Value
;
}
// Returns the value.
// PRE: Valid
const
T
*
operator
->
()
const
{
ASSERT
(
Valid
);
return
&
Value
;
}
// Returns the value.
// PRE: Valid
T
*
operator
->
()
{
ASSERT
(
Valid
);
return
&
Value
;
}
// Returns the value.
// PRE: Valid
T
&
value
()
{
ASSERT
(
Valid
);
return
Value
;
}
// Returns the value.
// PRE: Valid
const
T
&
value
()
const
{
ASSERT
(
Valid
);
return
Value
;
}
// Returns the value if Valid, otherwise returns DefaultValue.
const
T
&
valueOr
(
const
T
&
DefaultValue
)
const
{
return
Valid
?
Value
()
:
DefaultValue
;
}
private
:
void
destroy
()
{
if
(
Valid
)
{
Value
.
~
T
();
Valid
=
false
;
}
}
template
<
class
V
>
void
cr
(
V
&&
X
)
{
ASSERT
(
!
Valid
);
Valid
=
true
;
new
(
&
Value
)
T
(
std
::
forward
<
V
>
(
X
));
}
bool
Valid
;
union
{
T
Value
;
};
};
// Template specialization to allow Optional to hold a reference
// rather than an actual value with minimal overhead.
template
<
typename
T
>
class
Optional
<
T
&>
{
public
:
using
Type
=
T
;
Optional
(
const
none_t
&
=
none
)
:
Value
(
nullptr
)
{
// nop
}
Optional
(
T
&
X
)
:
Value
(
&
X
)
{
// nop
}
Optional
(
T
*
X
)
:
Value
(
X
)
{
// nop
}
Optional
(
const
Optional
&
Other
)
=
default
;
Optional
&
operator
=
(
const
Optional
&
Other
)
=
default
;
explicit
operator
bool
()
const
{
return
Value
!=
nullptr
;
}
bool
operator
!
()
const
{
return
!
Value
;
}
T
&
operator
*
()
{
ASSERT
(
Value
);
return
*
Value
;
}
const
T
&
operator
*
()
const
{
ASSERT
(
Value
);
return
*
Value
;
}
T
*
operator
->
()
{
ASSERT
(
Value
);
return
Value
;
}
const
T
*
operator
->
()
const
{
ASSERT
(
Value
);
return
Value
;
}
T
&
value
()
{
ASSERT
(
Value
);
return
*
Value
;
}
const
T
&
value
()
const
{
ASSERT
(
Value
);
return
*
Value
;
}
const
T
&
valueOr
(
const
T
&
DefaultValue
)
const
{
return
Value
?
Value
()
:
DefaultValue
;
}
private
:
T
*
Value
;
};
// Template specialization to allow Optional to implement a flag for void.
template
<>
class
Optional
<
void
>
{
public
:
using
Type
=
unit_t
;
Optional
(
none_t
=
none
)
:
Value
(
false
)
{
// nop
}
Optional
(
unit_t
)
:
Value
(
true
)
{
// nop
}
Optional
(
const
Optional
&
Other
)
=
default
;
Optional
&
operator
=
(
const
Optional
&
Other
)
=
default
;
explicit
operator
bool
()
const
{
return
Value
;
}
bool
operator
!
()
const
{
return
!
Value
;
}
private
:
bool
Value
;
};
}
// End namespace rosa
#endif
// ROSA_SUPPORT_TYPES_HPP
File Metadata
Details
Attached
Mime Type
text/x-c++
Expires
Wed, Jul 2, 12:07 PM (16 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157134
Default Alt Text
types.hpp (6 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment