1
/*
2
* \brief Utility for the manual placement of objects
3
* \author Norman Feske
4
* \date 2014-02-07
5
*/
6
7
/*
8
* Copyright (C) 2014 Genode Labs GmbH
9
*
10
* This file is part of the Genode OS framework, which is distributed
11
* under the terms of the GNU General Public License version 2.
12
*/
13
14
#
ifndef _INCLUDE__UTIL__CONSTRUCT_AT_H_
15
#
define _INCLUDE__UTIL__CONSTRUCT_AT_H_
16
17
#
include <base/stdint.h>
18
#
include <base/printf.h>
19
20
namespace
Genode {
21
22
template
<
typename
T
,
typename
.
.
.
ARGS
>
23
static
inline
T *
construct_at(
void *
,
ARGS &&
.
.
.
)
;
24
}
25
26
27
/**
28
* Construct object of given type at a specific location
29
*
30
* \param T object type
31
* \param at desired object location
32
* \param args list of arguments for the object constructor
33
*
34
* \return typed object pointer
35
*
36
* We use move semantics (ARGS &&) because otherwise the compiler would create
37
* a temporary copy of all arguments that have a reference type and use a
38
* reference to this copy instead of the original within this function.
39
*
40
* There is a slight difference between the object that is constructed by this
41
* function and a common object of the given type. If the destructor of the
42
* given type or of any base of the given type is virtual, the vtable of the
43
* returned object references an empty delete(void *) operator for that
44
* destructor. However, this shouldn`t be a problem as an object constructed by
45
* this function should never get destructed implicitely or through a delete
46
* expression.
47
*/
48
template
<
typename
T
,
typename
.
.
.
ARGS
>
49
static
inline
T *
Genode::
construct_at(
void *
at
,
ARGS &&
.
.
.
args
)
50
{
51
/**
52
* Utility to equip an existing type `T` with a placement new operator
53
*/
54
struct
Placeable :
T
55
{
56
Placeable(
ARGS &&
.
.
.
args
)
:
T(
args.
.
.
)
{
}
57
58
void *
operator
new
(
size_t
,
void *
ptr
)
{
return
ptr
;
}
59
void
operator
delete
(
void *
,
void *
)
{
}
60
61
/**
62
* Standard delete operator
63
*
64
* As we explicitely define one version of the delete operator, the
65
* compiler won`t implicitely define any delete version for this class.
66
* But if type T has a virtual destructor, the compiler implicitely
67
* defines a `virtual ~Placeable()` which needs the following operator.
68
*/
69
void
operator
delete
(
void *
)
70
{
71
PERR(
"cxx: Placeable::operator delete (void *) not supported."
)
;
72
}
73
}
;
74
75
/*
76
* If the args input to this function contains rvalues, the compiler would
77
* use the according rvalue references as lvalues at the following call if
78
* we don`t cast them back to rvalue references explicitely. We can not use
79
* lvalues here because the compiler can not bind them to rvalue references
80
* as expected by Placeable.
81
*/
82
return
new
(
at)
Placeable(
static_cast
<
ARGS &&
>
(
args)
.
.
.
)
;
83
}
84
85
#
endif /* _INCLUDE__UTIL__CONSTRUCT_AT_H_ */