Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F27032771
types.hpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Authored By
Unknown
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
Tue, Oct 27, 3:04 PM (4 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
410289
Default Alt Text
types.hpp (6 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline