Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F69985248
id_manager.hh
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Jul 4, 15:42
Size
9 KB
Mime Type
text/x-c++
Expires
Sat, Jul 6, 15:42 (2 d)
Engine
blob
Format
Raw Data
Handle
18775007
Attached To
rLIBMULTISCALE LibMultiScale
id_manager.hh
View Options
/**
* @file id_manager.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Mon Sep 08 23:40:22 2014
*
* @brief This is the generic manager of objects from their IDs (string)
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it
* under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale is distributed in the hope that it will be useful, but
* WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __LIBMULTISCALE_ID_MANAGER_HH__
#define __LIBMULTISCALE_ID_MANAGER_HH__
/* -------------------------------------------------------------------------- */
#include "lm_common.hh"
#include "lm_object.hh"
#include <algorithm>
#include <fstream>
#include <list>
#include <map>
#include <memory>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
struct
UnknownID
:
public
std
::
runtime_error
{
UnknownID
(
const
LMID
&
id
,
const
std
::
string
&
manager_type
)
:
std
::
runtime_error
(
"Unknown id: "
+
id
+
" from manager type: "
+
manager_type
),
id
(
id
)
{}
LMID
id
;
};
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
class
IDManager
{
public
:
friend
struct
std
::
default_delete
<
IDManager
<
T
>>
;
typedef
std
::
string
typeID
;
typedef
std
::
map
<
typeID
,
T
*>
Cont
;
protected
:
IDManager
();
virtual
~
IDManager
();
public
:
static
void
destroy
();
//! reset the communicator
void
reset
();
//! add a geometry as a shared pointer
typeID
addObject
(
std
::
shared_ptr
<
T
>
g
);
//! add a geometry as an object
typeID
addObject
(
T
&
g
);
//! generate a new id automatically
typeID
generateNewID
();
//! remove a managed object
void
removeObject
(
const
typeID
&
ID
);
//! remove a managed object
void
removeObject
(
const
T
&
ID
);
//! true if singleton already allocated
static
bool
allocated
()
{
return
static_pointer
!=
nullptr
;
}
//! applies a functor for each stored entry
template
<
typename
Func
>
void
for_each
(
Func
&&
func
)
{
std
::
for_each
(
this
->
objects
.
begin
(),
this
->
objects
.
end
(),
[
&
](
auto
&&
pair
)
{
func
(
*
pair
.
second
);
});
}
//! return a reference to a geometry from its ID
T
&
getObject
(
const
typeID
&
ID
);
//! return a shared_pointer from its ID
std
::
shared_ptr
<
T
>
getSharedObject
(
const
typeID
&
ID
);
//! return a casted object from its ID
template
<
typename
Cast
>
inline
Cast
&
getCastedObject
(
const
typeID
&
ID
);
//! search id of a given geometry
typeID
getID
(
T
&
obj
);
protected
:
//! accessor to the singleton manager
template
<
typename
IT
>
static
IT
&
getManager
();
//! mapping between IDs and pointers
std
::
map
<
typeID
,
T
*>
objects
;
//! mapping between IDs and shared pointers
std
::
map
<
typeID
,
std
::
shared_ptr
<
T
>>
shared_pointer_objects
;
//! file to which output the object infos
std
::
ofstream
fout
;
static
std
::
unique_ptr
<
IDManager
<
T
>>
static_pointer
;
std
::
list
<
typeID
>
insert_order
;
};
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
template
<
typename
IT
>
inline
IT
&
IDManager
<
T
>::
getManager
()
{
if
(
!
static_pointer
)
static_pointer
.
reset
(
new
IT
());
IT
&
ref
=
dynamic_cast
<
IT
&>
(
*
static_pointer
);
return
ref
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
IDManager
<
T
>::
IDManager
()
{
std
::
string
filename
=
"log."
;
filename
+=
typeinfo
<
decltype
(
*
this
)
>
();
fout
.
open
(
filename
.
c_str
(),
std
::
ios_base
::
out
);
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
typename
IDManager
<
T
>::
typeID
IDManager
<
T
>::
generateNewID
()
{
UInt
i
=
objects
.
size
();
std
::
stringstream
str
;
str
<<
"geom"
<<
i
;
return
str
.
str
();
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
typename
IDManager
<
T
>::
typeID
IDManager
<
T
>::
addObject
(
std
::
shared_ptr
<
T
>
obj
)
{
if
(
obj
==
nullptr
)
LM_FATAL
(
"attempt to register a null pointer as "
<<
typeid
(
*
this
).
name
());
typeID
id
=
obj
->
getID
();
if
(
objects
.
count
(
id
)
>
0
&&
objects
[
id
])
LM_FATAL
(
"ID "
<<
id
<<
" has already been used for "
<<
*
objects
[
id
]);
DUMP
(
"register object: "
<<
obj
.
get
(),
DBG_INFO
);
shared_pointer_objects
[
id
]
=
obj
;
objects
[
id
]
=
obj
.
get
();
DUMPFILE
(
fout
,
id
<<
"("
<<
*
obj
<<
") added to "
<<
typeinfo
<
decltype
(
*
this
)
>
()
<<
" manager"
);
insert_order
.
push_back
(
id
);
return
id
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
typename
IDManager
<
T
>::
typeID
IDManager
<
T
>::
addObject
(
T
&
obj
)
{
typeID
id
=
obj
.
getID
();
if
(
objects
.
count
(
id
)
>
0
&&
objects
[
id
])
LM_FATAL
(
"ID "
<<
id
<<
" has already been used for "
<<
*
objects
[
id
]);
objects
[
id
]
=
&
obj
;
DUMPFILE
(
fout
,
id
<<
"("
<<
obj
<<
") added to "
<<
typeinfo
<
decltype
(
*
this
)
>
()
<<
" manager"
);
insert_order
.
push_back
(
id
);
return
id
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
void
IDManager
<
T
>::
removeObject
(
const
T
&
obj
)
{
typeID
ID
=
obj
.
getID
();
removeObject
(
ID
);
DUMPFILE
(
fout
,
"removed "
<<
ID
<<
" from manager "
<<
typeinfo
<
decltype
(
*
this
)
>
());
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
void
IDManager
<
T
>::
removeObject
(
const
typeID
&
ID
)
{
if
(
objects
.
count
(
ID
)
==
0
)
{
DUMP
(
"impossible to delete entry -> unknown id: "
<<
ID
,
DBG_INFO
);
return
;
}
objects
.
erase
(
ID
);
if
(
shared_pointer_objects
.
count
(
ID
))
shared_pointer_objects
.
erase
(
ID
);
insert_order
.
remove
(
ID
);
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
T
&
IDManager
<
T
>::
getObject
(
const
typeID
&
ID
)
{
if
(
objects
.
count
(
ID
)
==
0
)
{
throw
UnknownID
(
ID
,
typeinfo
<
decltype
(
*
this
)
>
());
}
return
*
objects
[
ID
];
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
std
::
shared_ptr
<
T
>
IDManager
<
T
>::
getSharedObject
(
const
typeID
&
ID
)
{
if
(
shared_pointer_objects
.
count
(
ID
)
==
0
)
{
throw
UnknownID
(
ID
,
typeinfo
<
decltype
(
*
this
)
>
());
}
return
shared_pointer_objects
[
ID
];
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
template
<
typename
Cast
>
inline
Cast
&
IDManager
<
T
>::
getCastedObject
(
const
typeID
&
ID
)
{
std
::
string
component_name
=
ID
;
std
::
string
output_name
=
""
;
auto
pos
=
component_name
.
find
(
"."
);
if
(
pos
!=
std
::
string
::
npos
)
{
output_name
=
component_name
.
substr
(
pos
+
1
);
component_name
=
component_name
.
substr
(
0
,
pos
);
}
if
(
objects
.
count
(
component_name
)
==
0
)
{
throw
UnknownID
(
ID
,
typeinfo
<
decltype
(
*
this
)
>
());
}
Cast
*
ptr
=
nullptr
;
if
(
output_name
!=
""
)
ptr
=
&
objects
[
component_name
]
->
template
evalOutput
<
Cast
>
(
output_name
);
else
ptr
=
dynamic_cast
<
Cast
*>
(
objects
[
component_name
]);
if
(
!
ptr
)
{
LM_FATAL
(
"bad cast for ID: "
<<
ID
<<
" from "
<<
typeinfo
<
decltype
(
*
this
)
>
()
<<
" to "
<<
typeinfo
<
Cast
>
());
}
return
*
ptr
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
typename
IDManager
<
T
>::
typeID
IDManager
<
T
>::
getID
(
T
&
obj
)
{
for
(
auto
&&
o
:
objects
)
{
if
(
o
.
second
==
obj
)
return
o
.
first
;
}
DUMPFILE
(
fout
,
"Warning : auto registering of "
<<
this
->
getID
()
<<
" {
\n
"
<<
*
obj
<<
"
\n
}"
);
return
(
addObject
(
obj
));
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
IDManager
<
T
>::~
IDManager
()
{
destroy
();
DUMPFILE
(
fout
,
"all "
<<
typeinfo
<
decltype
(
*
this
)
>
()
<<
" cleaned..."
);
fout
.
close
();
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
void
IDManager
<
T
>::
destroy
()
{
if
(
static_pointer
==
nullptr
)
return
;
static_pointer
->
shared_pointer_objects
.
clear
();
if
(
static_pointer
)
static_pointer
.
release
();
}
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
inline
void
IDManager
<
T
>::
reset
()
{
this
->
shared_pointer_objects
.
clear
();
this
->
objects
.
clear
();
this
->
insert_order
.
clear
();
}
/* -------------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#endif
/* __LIBMULTISCALE_ID_MANAGER_HH__ */
Event Timeline
Log In to Comment