Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F64633818
component_libmultiscale.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
Tue, May 28, 07:53
Size
20 KB
Mime Type
text/x-c++
Expires
Thu, May 30, 07:53 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
17936113
Attached To
rLIBMULTISCALE LibMultiScale
component_libmultiscale.hh
View Options
/**
* @file component_libmultiscale.hh
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Mon Sep 08 23:40:22 2014
*
* @brief This describe the root objects to be combined into valid LM
* components
*
* @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_COMPONENT_LIBMULTISCALE_HH__
#define __LIBMULTISCALE_COMPONENT_LIBMULTISCALE_HH__
/* -------------------------------------------------------------------------- */
#include "container.hh"
#include "lm_common.hh"
#include "lm_object.hh"
/* -------------------------------------------------------------------------- */
#include <cmath>
#include <limits>
#include <map>
#include <memory>
#include <stdexcept>
#include <tuple>
#include <typeindex>
#include <typeinfo>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
/* -------------------------------------------------------------------------- */
using
dispatch
=
AutoDispatch
::
dispatch
;
template
<
typename
Tuple
>
struct
getFirstArgument
{
// this is a non used case....
// static int get(Tuple &) { return 10; };
};
template
<
typename
T
>
struct
getFirstArgument
<
std
::
tuple
<
T
>>
{
static
auto
&
get
(
std
::
tuple
<
T
>
&
tuple
)
{
return
std
::
get
<
0
>
(
tuple
);
}
};
/* -------------------------------------------------------------------------- */
template
<
typename
T
>
T
&&
make_argument
(
T
&&
a
)
{
return
std
::
forward
<
T
>
(
a
);
}
/* -------------------------------------------------------------------------- */
template
<
typename
T1
>
std
::
enable_if_t
<
std
::
is_base_of
<
ContainerInterface
,
std
::
decay_t
<
T1
>>::
value
>
_copyContainerInfo_casted
(
T1
&
value
,
ContainerInterface
&
a
)
{
value
.
copyContainerInfo
(
a
);
}
template
<
typename
T1
>
std
::
enable_if_t
<!
std
::
is_base_of
<
ContainerInterface
,
std
::
decay_t
<
T1
>>::
value
>
_copyContainerInfo_casted
(
T1
&
,
ContainerInterface
&
)
{}
template
<
typename
T1
>
void
_copyContainerInfo_casted
(
std
::
shared_ptr
<
T1
>
value
,
ContainerInterface
&
a
)
{
T1
&
v
=
*
value
;
_copyContainerInfo_casted
<
T1
>
(
v
,
a
);
}
template
<
typename
T1
>
std
::
enable_if_t
<
std
::
is_base_of
<
LMObject
,
std
::
decay_t
<
T1
>>::
value
>
_setCommGroup
(
T1
&
value
,
CommGroup
&
c
)
{
value
.
setCommGroup
(
c
);
}
template
<
typename
T1
>
std
::
enable_if_t
<!
std
::
is_base_of
<
LMObject
,
std
::
decay_t
<
T1
>>::
value
>
_setCommGroup
(
T1
&
,
CommGroup
&
)
{}
template
<
typename
T1
>
void
_setCommGroup
(
std
::
shared_ptr
<
T1
>
value
,
CommGroup
&
comm_group
)
{
T1
&
v
=
*
value
;
_setCommGroup
(
v
,
comm_group
);
}
class
Component
;
class
ArgumentContainer
:
public
AutoDispatch
::
ArgumentAny
{
public
:
ArgumentContainer
()
:
component
(
nullptr
){};
ArgumentContainer
(
Component
&
component
)
:
component
(
&
component
){};
ArgumentContainer
(
ArgumentContainer
&&
other
)
=
default
;
ReleasedObject
*
operator
->
()
{
return
&
this
->
get
();
}
ReleasedObject
&
operator
*
()
{
return
this
->
get
();
}
using
AutoDispatch
::
ArgumentAny
::
operator
=
;
UInt
getRelease
()
{
return
this
->
get
().
getRelease
();
}
void
setRelease
(
UInt
release
)
{
this
->
get
().
setRelease
(
release
);
}
ArgumentContainer
&
operator
=
(
ArgumentContainer
&&
arg
)
=
default
;
ArgumentContainer
&
operator
=
(
const
ArgumentContainer
&
arg
)
=
default
;
// if (ptr_allocated.get() != nullptr)
// ptr_allocated.release();
// ptr = arg.ptr;
// return *this;
// }
inline
ReleasedObject
&
get
(
bool
eval
=
true
);
inline
const
ReleasedObject
&
get
()
const
;
inline
bool
isAllocated
();
private
:
Component
*
component
;
};
/* --------------------------------------------------------------------- */
class
Component
:
public
ReleasedObject
,
public
virtual
LMObject
{
public
:
Component
()
:
me_as_argument
(
*
this
),
calculated_once
(
false
),
comm_group
(
nullptr
)
{
me_as_argument
=
*
this
;
}
virtual
~
Component
(){};
virtual
void
setCommGroup
(
CommGroup
&
group
)
{
comm_group
=
&
group
;
};
template
<
typename
T
>
void
connect
(
const
std
::
string
&
input
,
T
&&
arg
);
inline
void
connect
(
const
std
::
string
&
input
,
ArgumentContainer
&
arg
);
template
<
typename
...
Args
>
inline
void
setInput
(
Args
&&
...
args
)
{
auto
tup
=
std
::
forward_as_tuple
(
args
...);
int
cpt
=
0
;
std
::
vector
<
std
::
string
>
keys
;
std
::
for_each
(
inputs
.
begin
(),
inputs
.
end
(),
[
&
keys
](
auto
key
)
{
keys
.
push_back
(
key
.
first
);
});
auto
f
=
[
&
](
auto
&
arg
)
{
auto
key
=
keys
[
cpt
];
auto
search
=
inputs
.
find
(
key
);
if
(
search
==
inputs
.
end
())
{
LM_FATAL
(
this
->
getID
()
+
":"
+
key
+
": input not existing"
);
}
if
(
this
->
inputs
[
key
]
==
nullptr
)
this
->
inputs
[
key
]
=
new
ArgumentContainer
();
*
this
->
inputs
[
key
]
=
make_argument
(
arg
);
++
cpt
;
};
apply
(
f
,
tup
);
}
inline
ArgumentContainer
*
allocInput
(
const
std
::
string
&
input
);
inline
void
createOutput
(
const
std
::
string
&
output
);
inline
void
createInput
(
const
std
::
string
&
input
);
inline
void
removeInput
(
const
std
::
string
&
input
);
inline
bool
isConnected
(
const
std
::
string
&
input
);
virtual
void
compute
();
template
<
typename
...
Args
>
void
buildManual
(
Args
&&
...
args
)
{
this
->
setInput
(
args
...);
this
->
compute_make_call
();
calculated_once
=
true
;
}
template
<
typename
T
>
std
::
enable_if_t
<
std
::
is_base_of
<
ContainerInterface
,
T
>::
value
>
_copyContainerInfo
(
T
&
a
)
{
for
(
auto
&
output
:
this
->
outputs
)
{
auto
&
o
=
output
.
second
.
get
(
false
);
try
{
o
.
cast
<
ContainerInterface
>
().
copyContainerInfo
(
a
);
}
catch
(
std
::
bad_cast
&
)
{
// if not a container cannot do anything
}
}
}
virtual
void
compute_make_call
()
=
0
;
inline
ArgumentContainer
&
getInput
(
const
std
::
string
&
requested_input
=
""
)
{
std
::
string
input
=
requested_input
;
if
(
input
==
""
)
{
if
(
this
->
inputs
.
size
()
==
0
)
{
LM_FATAL
(
"There is no input for "
<<
this
->
getID
());
}
else
if
(
this
->
inputs
.
size
()
!=
1
)
{
std
::
string
mesg
=
this
->
getID
()
+
" has several inputs: need a name"
;
mesg
+=
"
\n\n
Possible names:
\n\n
"
;
for
(
auto
&&
pair
:
this
->
inputs
)
{
mesg
+=
"
\t
"
+
pair
.
first
+
"
\n
"
;
}
LM_FATAL
(
mesg
);
}
input
=
this
->
inputs
.
begin
()
->
first
;
}
else
{
auto
search
=
inputs
.
find
(
input
);
if
(
search
==
inputs
.
end
())
{
LM_FATAL
(
this
->
getID
()
+
":"
+
input
+
": input not existing"
);
}
}
ArgumentContainer
*
arg_cont_input
=
inputs
[
input
];
if
(
arg_cont_input
==
nullptr
)
throw
UnconnectedInput
{
"For component '"
+
this
->
getID
()
+
"' input '"
+
input
+
"' is not connected"
};
return
*
arg_cont_input
;
}
inline
auto
&
getOutputs
()
{
return
outputs
;
}
inline
auto
&
getInputs
()
{
return
inputs
;
}
inline
ArgumentContainer
&
getOutput
(
const
std
::
string
&
output_name
=
""
)
{
auto
name
=
output_name
;
if
(
name
==
""
)
{
if
(
this
->
outputs
.
size
()
==
0
)
{
LM_FATAL
(
"There is no output for "
<<
this
->
getID
());
}
else
if
(
this
->
outputs
.
size
()
!=
1
)
{
std
::
string
mesg
=
this
->
getID
()
+
" has several outputs: need a name"
;
mesg
+=
"
\n\n
Possible names:
\n\n
"
;
for
(
auto
&&
pair
:
this
->
outputs
)
{
mesg
+=
"
\t
"
+
pair
.
first
+
"
\n
"
;
}
LM_FATAL
(
mesg
);
}
name
=
this
->
outputs
.
begin
()
->
first
;
}
auto
search
=
outputs
.
find
(
name
);
if
(
search
==
outputs
.
end
())
{
std
::
string
mesg
=
this
->
getID
()
+
":"
+
name
+
": output not existing"
;
mesg
+=
"
\n\n
Possible names:
\n\n
"
;
for
(
auto
&&
pair
:
this
->
outputs
)
{
mesg
+=
"
\t
"
+
pair
.
first
+
"
\n
"
;
}
LM_FATAL
(
mesg
);
}
return
outputs
[
name
];
};
template
<
typename
Cont
>
auto
&
getCastedOutput
(
const
std
::
string
&
output_name
,
bool
eval
=
true
)
{
auto
&
arg
=
this
->
getOutput
(
output_name
).
get
(
eval
);
return
arg
.
cast
<
Cont
>
();
}
template
<
typename
Cont
,
typename
...
T
>
auto
&
allocAndGetCastedOutput
(
const
std
::
string
&
output_name
,
T
&&
...
construction_parameters
)
{
using
type
=
typename
Cont
::
ContainerSubset
;
using
ptr_type
=
std
::
shared_ptr
<
type
>
;
try
{
this
->
getCastedOutput
<
ptr_type
>
(
output_name
,
false
);
}
catch
(
AutoDispatch
::
no_argument
&
e
)
{
this
->
getOutput
(
output_name
)
=
make_argument
(
std
::
make_shared
<
type
>
(
construction_parameters
...));
}
auto
&
output
=
*
getCastedOutput
<
ptr_type
>
(
output_name
,
false
);
return
output
;
}
inline
void
printself
(
std
::
ostream
&
os
)
const
;
void
clear_inputs
()
{
inputs
.
clear
();
}
struct
UnconnectedInput
:
public
std
::
runtime_error
{
using
std
::
runtime_error
::
runtime_error
;
};
struct
NotInCommGroup
:
public
std
::
runtime_error
{
using
std
::
runtime_error
::
runtime_error
;
};
ArgumentContainer
&
toArgContainer
()
{
return
me_as_argument
;
}
template
<
typename
T
=
Real
>
ContainerArray
<
T
>
&
getArray
(
const
std
::
string
&
output_name
=
""
)
{
return
this
->
getCastedOutput
<
ContainerArray
<
T
>>
(
output_name
,
false
);
}
template
<
typename
Names
>
void
createArrayOutputs
(
Names
&&
output_names
)
{
for
(
auto
&&
f
:
output_names
)
{
this
->
createArrayOutput
(
f
);
}
}
template
<
typename
T
=
Real
>
void
createArrayOutput
(
const
std
::
string
&
name
)
{
this
->
createOutput
(
name
);
this
->
getOutput
(
name
)
=
make_argument
(
ContainerArray
<
T
>
(
this
->
getID
()
+
":"
+
name
));
}
private
:
ArgumentContainer
me_as_argument
;
friend
class
ActionInterface
;
std
::
map
<
std
::
string
,
ArgumentContainer
*>
inputs
;
std
::
map
<
std
::
string
,
ArgumentContainer
>
outputs
;
std
::
map
<
std
::
string
,
std
::
unique_ptr
<
ArgumentContainer
>>
allocated_inputs
;
bool
calculated_once
;
CommGroup
*
comm_group
;
};
inline
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Component
&
comp
)
{
comp
.
printself
(
os
);
return
os
;
}
void
Component
::
printself
(
std
::
ostream
&
os
)
const
{
for
(
auto
&
pair
:
this
->
inputs
)
{
os
<<
"input "
<<
pair
.
first
<<
":"
;
if
(
pair
.
second
!=
nullptr
)
os
<<
pair
.
second
->
get
()
<<
"
\n
"
;
else
os
<<
"not yet defined/computed
\n
"
;
}
for
(
auto
&
pair
:
this
->
outputs
)
{
os
<<
"output "
<<
pair
.
first
<<
":"
;
try
{
os
<<
pair
.
second
.
get
()
<<
"
\n
"
;
}
catch
(...)
{
os
<<
"not yet defined/computed
\n
"
;
}
}
}
void
Component
::
connect
(
const
std
::
string
&
input
,
ArgumentContainer
&
arg
)
{
auto
search
=
inputs
.
find
(
input
);
if
(
search
==
inputs
.
end
())
{
LM_FATAL
(
this
->
getID
()
+
":"
+
typeinfo
<
decltype
(
*
this
)
>
()
+
":"
+
input
+
": input not existing"
);
}
inputs
[
input
]
=
&
arg
;
}
template
<
typename
T
>
void
Component
::
connect
(
const
std
::
string
&
input
,
T
&&
arg
)
{
auto
search
=
inputs
.
find
(
input
);
if
(
search
==
inputs
.
end
())
{
LM_FATAL
(
this
->
getID
()
+
":"
+
typeinfo
<
decltype
(
*
this
)
>
()
+
":"
+
input
+
": input not existing"
);
}
if
(
inputs
[
input
]
==
nullptr
)
{
inputs
[
input
]
=
allocInput
(
input
);
}
*
inputs
[
input
]
=
std
::
move
(
arg
);
}
ArgumentContainer
*
Component
::
allocInput
(
const
std
::
string
&
input
)
{
allocated_inputs
[
input
]
=
std
::
make_unique
<
ArgumentContainer
>
();
return
allocated_inputs
[
input
].
get
();
}
void
Component
::
createOutput
(
const
std
::
string
&
output
)
{
outputs
[
output
]
=
ArgumentContainer
(
*
this
);
}
void
Component
::
createInput
(
const
std
::
string
&
input
)
{
inputs
[
input
]
=
nullptr
;
}
void
Component
::
removeInput
(
const
std
::
string
&
input
)
{
inputs
.
erase
(
input
);
}
bool
Component
::
isConnected
(
const
std
::
string
&
input
)
{
return
inputs
.
count
(
input
)
>
0
&&
inputs
[
input
]
!=
nullptr
;
}
/* --------------------------------------------------------------------- */
ReleasedObject
&
ArgumentContainer
::
get
(
bool
eval
)
{
if
(
this
->
component
!=
nullptr
&&
eval
)
{
this
->
component
->
compute
();
}
return
AutoDispatch
::
ArgumentAny
::
get
<
ReleasedObject
>
();
}
/* --------------------------------------------------------------------- */
const
ReleasedObject
&
ArgumentContainer
::
get
()
const
{
return
AutoDispatch
::
ArgumentAny
::
get
<
ReleasedObject
>
();
}
/* --------------------------------------------------------------------- */
template
<
int
n
>
struct
CopyContainerInfo
{
template
<
typename
Tuple
,
typename
Obj
>
static
void
copy
(
Tuple
&&
tuple_args
,
Obj
&
obj
)
{
if
(
n
==
1
)
{
// if a single argument, try to copyContainerInfo
auto
&&
a
=
std
::
get
<
0
>
(
tuple_args
);
obj
.
_copyContainerInfo
(
a
);
}
}
};
/* --------------------------------------------------------------------- */
template
<
typename
Output
,
typename
Component
>
class
SingleOutputComponent
:
public
Component
{
public
:
using
Component
::
Component
;
SingleOutputComponent
(
const
LMID
&
name
)
:
LMObject
(
name
),
Component
(
name
)
{}
operator
Output
&
()
{
return
this
->
getOutputs
().
begin
()
->
second
.
get
().
template
cast
<
Output
>
();
}
auto
begin
()
{
return
(
*
this
)
->
begin
();
}
auto
end
()
{
return
(
*
this
)
->
end
();
}
Output
*
operator
->
()
{
return
&
static_cast
<
Output
&>
(
*
this
);
}
Output
&
operator
*
()
{
return
*
this
;
}
};
template
<
typename
T
>
struct
casted_component
{
template
<
typename
CastT
>
using
cast
=
SingleOutputComponent
<
CastT
,
T
>
;
};
/* --------------------------------------------------------------------- */
#include <boost/preprocessor.hpp>
// ************ Should boost this ***********************************
// #include "atom_model_list.hh"
// #include "continuum_model_list.hh"
// #include "dd_model_list.hh"
// ******************************************************************
template
<
UInt
Dim
>
class
RefPoint
;
template
<
UInt
Dim
>
class
RefPointData
;
template
<
UInt
Dim
>
class
RefGenericElem
;
template
<
typename
T
>
class
ContainerArray
;
class
ComputeInterface
;
template
<
typename
ContNode
,
typename
ContElem
>
class
ContainerMesh
;
template
<
UInt
Dim
>
using
ContainerGenericMesh
=
ContainerMesh
<
ContainerArray
<
RefPointData
<
Dim
>>
,
ContainerArray
<
RefGenericElem
<
Dim
>>>
;
// possible containers of MD
#ifdef LIBMULTISCALE_MD1D
class
ContainerMD1D
;
class
RefMD1D
;
#endif
#ifdef LIBMULTISCALE_LAMMPS_PLUGIN
template
<
UInt
Dim
>
class
ContainerLammps
;
template
<
UInt
Dim
>
class
RefLammps
;
#endif
using
md_containers
=
std
::
tuple
<
#ifdef LIBMULTISCALE_MD1D
ContainerMD1D
,
ContainerArray
<
RefMD1D
>
#endif
#if defined(LIBMULTISCALE_LAMMPS_PLUGIN) && defined(LIBMULTISCALE_MD1D)
,
#endif
#ifdef LIBMULTISCALE_LAMMPS_PLUGIN
ContainerLammps
<
2
>
,
ContainerLammps
<
3
>
,
ContainerArray
<
RefLammps
<
2
>>
,
ContainerArray
<
RefLammps
<
3
>>
#endif
>
;
using
MD
=
md_containers
;
#ifdef LIBMULTISCALE_PARADIS_PLUGIN
class
ContainerNodesParaDiS
;
class
ContainerElemsParaDiS
;
class
RefNodeParaDiS
;
class
RefElemParaDiS
;
#endif
template
<
UInt
Dim
>
class
RefGenericDDElem
;
template
<
UInt
Dim
>
class
RefGenericDDNode
;
template
<
UInt
Dim
>
using
ContainerGenericDDMesh
=
ContainerMesh
<
ContainerArray
<
RefGenericDDNode
<
Dim
>>
,
ContainerArray
<
RefGenericDDElem
<
Dim
>>>
;
// possible containers of DD
using
dd_containers
=
std
::
tuple
<
ContainerGenericDDMesh
<
2u
>
,
ContainerGenericDDMesh
<
3u
>
#ifdef LIBMULTISCALE_PARADIS_PLUGIN
,
ContainerMesh
<
ContainerNodesParaDiS
,
ContainerElemsParaDiS
>
,
ContainerMesh
<
ContainerArray
<
RefNodeParaDiS
>
,
ContainerArray
<
RefElemParaDiS
>>
#endif
>
;
using
DD
=
dd_containers
;
// possible containers of CONTINUUM
#ifdef LIBMULTISCALE_MECA1D
class
ContainerElemsMeca1D
;
class
ContainerNodesMeca1D
;
class
RefNodeMeca1D
;
class
RefElemMeca1D
;
#endif
#ifdef LIBMULTISCALE_AKANTU_PLUGIN
template
<
UInt
Dim
>
class
ContainerElemsAkantu
;
template
<
UInt
Dim
>
class
ContainerNodesAkantu
;
template
<
UInt
Dim
>
class
RefNodeAkantu
;
template
<
UInt
Dim
>
class
RefElemAkantu
;
#endif
using
continuum_containers
=
std
::
tuple
<
#ifdef LIBMULTISCALE_MECA1D
ContainerMesh
<
ContainerNodesMeca1D
,
ContainerElemsMeca1D
>
,
ContainerMesh
<
ContainerArray
<
RefNodeMeca1D
>
,
ContainerArray
<
RefElemMeca1D
>>
#endif
#if defined(LIBMULTISCALE_MECA1D) && defined(LIBMULTISCALE_AKANTU_PLUGIN)
,
#endif
#ifdef LIBMULTISCALE_AKANTU_PLUGIN
ContainerMesh
<
ContainerNodesAkantu
<
1
>
,
ContainerElemsAkantu
<
1
>>
,
ContainerMesh
<
ContainerArray
<
RefNodeAkantu
<
1
>>
,
ContainerArray
<
RefElemAkantu
<
1
>>>
,
ContainerMesh
<
ContainerNodesAkantu
<
2
>
,
ContainerElemsAkantu
<
2
>>
,
ContainerMesh
<
ContainerArray
<
RefNodeAkantu
<
2
>>
,
ContainerArray
<
RefElemAkantu
<
2
>>>
,
ContainerMesh
<
ContainerNodesAkantu
<
3
>
,
ContainerElemsAkantu
<
3
>>
,
ContainerMesh
<
ContainerArray
<
RefNodeAkantu
<
3
>>
,
ContainerArray
<
RefElemAkantu
<
3
>>>
#endif
>
;
using
CONTINUUM
=
continuum_containers
;
// possible containers of points
using
point_containers
=
std
::
tuple
<
ContainerArray
<
RefPointData
<
1u
>>
,
ContainerArray
<
RefPointData
<
2u
>>
,
ContainerArray
<
RefPointData
<
3u
>>>
;
using
POINT
=
point_containers
;
// possible containers of meshes
using
mesh_containers
=
std
::
tuple
<
ContainerGenericMesh
<
1u
>
,
ContainerGenericMesh
<
2u
>
,
ContainerGenericMesh
<
3u
>>
;
using
MESH
=
mesh_containers
;
// possible computes as input
using
COMPONENT
=
std
::
tuple
<
Component
>
;
using
ARRAY
=
std
::
tuple
<
ContainerArray
<
Real
>>
;
/* --------------------------------------------------------------------- */
template
<
typename
T
,
typename
Tuple
>
struct
has_type
;
template
<
typename
T
>
struct
has_type
<
T
,
std
::
tuple
<>>
:
std
::
false_type
{};
template
<
typename
T
,
typename
U
,
typename
...
Ts
>
struct
has_type
<
T
,
std
::
tuple
<
U
,
Ts
...
>>
:
has_type
<
T
,
std
::
tuple
<
Ts
...
>>
{};
template
<
typename
T
,
typename
...
Ts
>
struct
has_type
<
T
,
std
::
tuple
<
T
,
Ts
...
>>
:
std
::
true_type
{};
/* --------------------------------------------------------------------- */
template
<
typename
T
,
typename
RetT
=
void
>
struct
_enable_if_md
:
std
::
enable_if
<
has_type
<
T
,
md_containers
>::
value
,
RetT
>
{
};
template
<
typename
T
,
typename
RetT
=
void
>
using
enable_if_md
=
typename
_enable_if_md
<
T
,
RetT
>::
type
;
template
<
typename
T
,
typename
RetT
=
void
>
struct
_enable_if_mesh
:
std
::
enable_if
<
has_type
<
T
,
mesh_containers
>::
value
or
has_type
<
T
,
continuum_containers
>::
value
or
has_type
<
T
,
dd_containers
>::
value
,
RetT
>
{};
template
<
typename
T
,
typename
RetT
=
void
>
using
enable_if_mesh
=
typename
_enable_if_mesh
<
T
,
RetT
>::
type
;
template
<
typename
T
,
typename
RetT
=
void
>
struct
_enable_if_continuum
:
std
::
enable_if
<
has_type
<
T
,
continuum_containers
>::
value
,
RetT
>
{};
template
<
typename
T
,
typename
RetT
=
void
>
using
enable_if_continuum
=
typename
_enable_if_continuum
<
T
,
RetT
>::
type
;
template
<
typename
T
,
typename
RetT
=
void
>
struct
_enable_if_point
:
std
::
enable_if
<
has_type
<
T
,
md_containers
>::
value
or
has_type
<
T
,
point_containers
>::
value
,
RetT
>
{};
template
<
typename
T
,
typename
RetT
=
void
>
using
enable_if_point
=
typename
_enable_if_point
<
T
,
RetT
>::
type
;
template
<
typename
T
,
typename
RetT
=
void
>
struct
_enable_if_dd
:
std
::
enable_if
<
has_type
<
T
,
dd_containers
>::
value
,
RetT
>
{
};
template
<
typename
T
,
typename
RetT
=
void
>
using
enable_if_dd
=
typename
_enable_if_dd
<
T
,
RetT
>::
type
;
template
<
typename
T
,
typename
RetT
=
void
>
struct
_enable_if_component
:
std
::
enable_if
<
std
::
is_same
<
T
,
Component
>::
value
,
RetT
>
{};
template
<
typename
T
,
typename
RetT
=
void
>
using
enable_if_component
=
typename
_enable_if_component
<
T
,
RetT
>::
type
;
template
<
typename
T
,
typename
RetT
=
void
>
struct
_enable_if_not_component
:
std
::
enable_if
<
not
std
::
is_same
<
T
,
Component
>::
value
,
RetT
>
{};
template
<
typename
T
,
typename
RetT
=
void
>
using
enable_if_not_component
=
typename
_enable_if_not_component
<
T
,
RetT
>::
type
;
/* --------------------------------------------------------------------- */
#define DECLARE_INPUT(...) \
using possible_types = std::tuple<std::tuple<__VA_ARGS__>>
#define DECLARE_MULTIPLE_INPUT(...) \
using possible_types = std::tuple<__VA_ARGS__>
/* --------------------------------------------------------------------- */
__END_LIBMULTISCALE__
#endif
/* __LIBMULTISCALE_COMPONENT_LIBMULTISCALE_HH__ */
Event Timeline
Log In to Comment