PLaSK library
Loading...
Searching...
No Matches
provider.hpp
Go to the documentation of this file.
1
/*
2
* This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3
* Copyright (c) 2022 Lodz University of Technology
4
*
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, version 3.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*/
14
#ifndef PLASK__PROVIDER_H
15
#define PLASK__PROVIDER_H
16
165
#include <set>
166
#include <vector>
167
#include <functional>
// std::function
168
#include <type_traits>
// std::is_same
169
#include "../optional.hpp"
170
#include <boost/signals2.hpp>
171
172
173
#include "../exceptions.hpp"
174
#include "../utils/stl.hpp"
175
#include "../mesh/mesh.hpp"
176
#include "../mesh/interpolation.hpp"
177
178
namespace
plask
{
179
190
struct
PLASK_API
Provider
{
191
192
static
constexpr
const
char
* NAME =
"undefined"
;
193
virtual
const
char
*
name
()
const
{
return
NAME; }
194
195
Provider
&
operator=
(
const
Provider
&) =
delete
;
196
Provider
(
const
Provider
&) =
delete
;
197
Provider
() =
default
;
198
203
boost::signals2::signal<
void
(
Provider
&,
bool
)>
changed
;
204
206
virtual
~Provider
() {
207
changed(*
this
,
true
);
208
}
209
214
void
fireChanged
() {
215
changed(*
this
,
false
);
216
}
217
218
};
219
224
struct
PLASK_API
ReceiverBase
{
225
227
enum class
ChangeReason
{
228
REASON_DELETE,
229
REASON_VALUE,
230
REASON_PROVIDER
231
};
232
233
virtual
~ReceiverBase
() {}
234
};
235
249
template
<
typename
Prov
id
erT>
250
class
Receiver
:
public
ReceiverBase
{
251
252
boost::signals2::connection providerConnection;
253
254
protected
:
255
257
bool
_hasPrivateProvider
;
258
259
public
:
260
261
typedef
Receiver<ProviderT>
Base
;
262
264
static
constexpr
const
char
*
PROVIDER_NAME
= ProviderT::NAME;
265
virtual
const
char
*
providerName
()
const
{
return
PROVIDER_NAME
; }
266
268
boost::signals2::signal<
void
(
ReceiverBase
& src,
ChangeReason
reason
)>
providerValueChanged
;
269
270
Receiver
&
operator=
(
const
Receiver
&) =
delete
;
271
Receiver
(
const
Receiver
&) =
delete
;
272
274
typedef
ProviderT
ProviderType
;
275
277
ProviderT
*
provider
;
278
280
Receiver
():
_hasPrivateProvider
(
false
),
provider
(0) {}
281
283
virtual
~Receiver
() {
284
providerConnection.disconnect();
285
if
(
_hasPrivateProvider
) {
286
delete
this->
provider
;
287
this->provider =
nullptr
;
288
}
289
fireChanged
(
ChangeReason::REASON_DELETE
);
290
}
291
296
void
fireChanged
(
ChangeReason
reason
) {
297
providerValueChanged
(*
this
,
reason
);
298
}
299
305
void
setProvider
(
ProviderT
*
provider
,
bool
newProviderIsPrivate
=
false
) {
306
if
(this->provider ==
provider
) {
307
this->_hasPrivateProvider =
newProviderIsPrivate
;
308
return
;
309
}
310
providerConnection.disconnect();
311
if
(
_hasPrivateProvider
)
delete
this->
provider
;
312
if
(provider) providerConnection =
provider
->changed.connect(
313
[&](
Provider
&
PLASK_UNUSED
(which),
bool
isDeleted
) {
314
if
(
isDeleted
) {
315
providerConnection.disconnect();
//TODO do we need this line?
316
this->provider = 0;
317
}
318
this->
fireChanged
(isDeleted ?
ChangeReason::REASON_PROVIDER
:
ChangeReason::REASON_VALUE
);
319
});
320
this->provider =
provider
;
321
this->_hasPrivateProvider =
newProviderIsPrivate
;
322
this->
fireChanged
(
ChangeReason::REASON_PROVIDER
);
323
}
324
329
void
setProvider
(
ProviderT
&provider) {
330
setProvider
(&
provider
);
331
}
332
337
void
setProvider
(std::unique_ptr<ProviderT>&&
provider
) {
338
setProvider
(
provider
->release(),
true
);
339
}
340
341
/*
342
* Change provider. If new provider is different from current one then changed flag is set.
343
* @param provider new provider, can be @c nullptr to only disconnect from current provider.
344
*/
345
/*void operator=(ProviderT *provider) {
346
setProvider(provider);
347
}*/
348
349
/*
350
* Change provider. If new provider is different from current one then changed flag is set.
351
* @param provider new provider
352
*/
353
/*void operator=(ProviderT &provider) {
354
setProvider(&provider);
355
}*/
356
361
ProviderT
*
getProvider
() {
return
provider
; }
362
367
const
ProviderT
*
getProvider
()
const
{
return
provider
; }
368
370
bool
hasProvider
()
const
{
371
return
provider
;
372
}
373
375
void
ensureHasProvider
()
const
{
376
if
(
provider
==
nullptr
)
377
throw
NoProvider
(
providerName
());
378
}
379
386
template
<
typename
...Args>
auto
387
operator()
(
const
Args
&... params)
const
->
decltype
((*provider)(params...)) {
388
beforeGetValue
();
389
return
(*
provider
)(params...);
390
}
391
397
template
<
typename
...Args>
auto
398
optional
(
const
Args
&... params)
const
-> plask::optional<
decltype
((*provider)(params...))> {
399
try
{
400
return
plask::optional<
decltype
((*provider)(params...))>(this->
operator
()(params...));
401
}
catch
(std::exception&) {
402
return
plask::optional<
decltype
((*provider)(params...))>();
403
}
404
}
405
412
template
<
typename
...ConstProviderConstructorArgs>
413
void
setConstValue
(
ConstProviderConstructorArgs
&&...
constProviderConstructorArgs
) {
414
setProvider
(
new
typename
ProviderT::ConstProviderType(std::forward<ConstProviderConstructorArgs>(
constProviderConstructorArgs
)...),
true
);
415
}
416
424
template
<
typename
ClassT,
typename
methodT>
425
boost::signals2::connection
changedConnectMethod
(
ClassT
* obj,
methodT
method, boost::signals2::connect_position at=boost::signals2::at_back) {
426
return
providerValueChanged
.connect(boost::bind(method, obj,
_1
,
_2
), at);
427
}
428
430
template
<
typename
ClassT,
typename
methodT>
431
void
changedDisconnectMethod
(
ClassT
* obj,
methodT
method) {
432
providerValueChanged
.disconnect(boost::bind(method, obj,
_1
,
_2
));
433
}
434
435
protected
:
436
445
void
beforeGetValue
()
const
{
446
ensureHasProvider
();
447
}
448
449
};
450
456
template
<
typename
ValueT
,
typename
...
ArgsT
>
457
struct
SingleValueProvider
:
public
Provider
{
458
459
static
constexpr
const
char
*
NAME
=
"undefined value"
;
460
const
char
*
name
()
const override
{
return
NAME
; }
461
463
typedef
ValueT
ProvidedType
;
464
469
virtual
ProvidedType
operator()
(
ArgsT
...)
const
= 0;
470
471
};
472
478
template
<
typename
ValueT
,
typename
EnumT
,
typename
...
ArgsT
>
479
struct
MultiValueProvider
:
public
Provider
{
480
481
static
constexpr
const
char
*
NAME
=
"undefined value"
;
482
const
char
*
name
()
const override
{
return
NAME
; }
483
485
typedef
ValueT
ProvidedType
;
486
488
typedef
EnumT
EnumType
;
489
494
virtual
ProvidedType
operator()
(
EnumT
num,
ArgsT
...)
const
= 0;
495
500
virtual
size_t
size
()
const
= 0;
501
502
};
503
504
//TODO typedef for SingleValueReceiver (GCC 4.7 needed)
505
510
template
<
typename
ValueT
,
typename
SpaceT
,
typename
...
ExtraArgs
>
511
struct
FieldProvider
:
public
Provider
{
512
513
static
constexpr
const
char
*
NAME
=
"undefined field"
;
514
const
char
*
name
()
const override
{
return
NAME
; }
515
517
typedef
LazyData<ValueT>
ProvidedType
;
518
typedef
SpaceT
SpaceType
;
519
526
virtual
ProvidedType
operator()
(shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh,
ExtraArgs
...
extra_args
,
InterpolationMethod
method)
const
= 0;
527
534
inline
ProvidedType
operator()
(shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh,
ExtraArgs
...
extra_args
)
const
{
535
return
this->
operator()
(dst_mesh,
extra_args
...,
INTERPOLATION_DEFAULT
);
536
}
537
544
inline
ProvidedType
operator()
(shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh, std::tuple<ExtraArgs...>
extra_args
,
InterpolationMethod
method =
INTERPOLATION_DEFAULT
)
const
{
545
typedef
std::tuple<
ExtraArgs
...>
Tuple
;
546
return
apply_tuple(dst_mesh, method, std::forward<Tuple>(
extra_args
),
make_seq_indices
<0,
sizeof
...(
ExtraArgs
)>{});
547
}
548
549
private
:
550
template
<
typename
T,
template
<std::size_t...>
class
I
, std::size_t...
Indices
>
551
inline
ProvidedType
apply_tuple(shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh,
InterpolationMethod
method, T&& t,
I<Indices...>
)
const
{
552
return
this->
operator()
(dst_mesh, std::get<Indices>(std::forward<T>(t))..., method);
553
}
554
555
};
556
561
template
<
typename
ValueT
,
typename
SpaceT
,
typename
EnumT
,
typename
...
ExtraArgs
>
562
struct
MultiFieldProvider
:
public
Provider
{
563
564
static
constexpr
const
char
*
NAME
=
"undefined field"
;
565
const
char
*
name
()
const override
{
return
NAME
; }
566
568
typedef
LazyData<ValueT>
ProvidedType
;
569
571
typedef
EnumT
EnumType
;
572
577
virtual
size_t
size
()
const
= 0;
578
586
virtual
ProvidedType
operator()
(
EnumT
num, shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh,
ExtraArgs
...
extra_args
,
InterpolationMethod
method)
const
= 0;
587
595
inline
ProvidedType
operator()
(
EnumT
num, shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh,
ExtraArgs
...
extra_args
)
const
{
596
return
this->
operator()
(num, dst_mesh,
extra_args
...,
INTERPOLATION_DEFAULT
);
597
}
598
606
inline
ProvidedType
operator()
(
EnumT
num, shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh, std::tuple<ExtraArgs...>&&
extra_args
,
InterpolationMethod
method =
INTERPOLATION_DEFAULT
)
const
{
607
typedef
std::tuple<
ExtraArgs
...>
Tuple
;
608
return
apply_tuple(num, dst_mesh, method, std::forward<Tuple>(
extra_args
),
make_seq_indices
<0,
sizeof
...(
ExtraArgs
)>{});
609
}
610
618
inline
ProvidedType
operator()
(shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh,
ExtraArgs
...
extra_args
,
InterpolationMethod
method)
const
{
619
return
this->
operator()
(
EnumT
(0), dst_mesh,
extra_args
..., method);
620
}
621
628
inline
ProvidedType
operator()
(shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh,
ExtraArgs
...
extra_args
)
const
{
629
return
this->
operator()
(
EnumT
(0), dst_mesh,
extra_args
...,
INTERPOLATION_DEFAULT
);
630
}
631
639
inline
ProvidedType
operator()
(shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh, std::tuple<ExtraArgs...>&&
extra_args
,
InterpolationMethod
method =
INTERPOLATION_DEFAULT
)
const
{
640
typedef
std::tuple<
ExtraArgs
...>
Tuple
;
641
return
apply_tuple(
EnumT
(0), dst_mesh, method, std::forward<Tuple>(
extra_args
),
make_seq_indices
<0,
sizeof
...(
ExtraArgs
)>{});
642
}
643
644
private
:
645
template
<
typename
T,
template
<std::size_t...>
class
I
, std::size_t...
Indices
>
646
inline
ProvidedType
apply_tuple(
size_t
num, shared_ptr<
const
MeshD<SpaceT::DIM>
> dst_mesh,
InterpolationMethod
method, T&& t,
I<Indices...>
) {
647
return
this->
operator()
(num, dst_mesh, std::get<Indices>(std::forward<T>(t))..., method);
648
}
649
650
};
651
652
653
template
<
typename
_Signature>
struct
DelegateProvider
;
654
660
template
<
typename
_Res
,
typename
...
_ArgTypes
>
661
struct
DelegateProvider
<
_Res
(
_ArgTypes
...)>:
public
Provider
{
662
664
std::function<
_Res
(
_ArgTypes
...)> valueGetter;
665
670
template
<
typename
...Args>
671
DelegateProvider
<
_Res
(
_ArgTypes
...)>(
Args
&&... params)
672
: valueGetter(
std
::
forward
<
Args
>(params)...) {
673
}
674
680
virtual
_Res
operator()
(
_ArgTypes
&&... params)
const
{
681
return
valueGetter(std::forward<_ArgTypes>(params)...);
682
}
683
};
684
685
template
<
typename
_BaseClass,
typename
_Signature>
struct
PolymorphicDelegateProvider
;
686
692
template
<
typename
_BaseClass,
typename
_Res
,
typename
...
_ArgTypes
>
693
struct
PolymorphicDelegateProvider
<_BaseClass,
_Res
(
_ArgTypes
...)>:
public
_BaseClass {
694
695
697
std::function<
_Res
(
_ArgTypes
...)>
valueGetter
;
698
699
PolymorphicDelegateProvider
() =
delete
;
700
705
template
<
typename
Functor>
706
PolymorphicDelegateProvider
<_BaseClass,
_Res
(
_ArgTypes
...)>(
Functor
functor)
707
: valueGetter(functor)
708
{}
709
715
template
<
typename
ClassType,
typename
MemberType>
716
PolymorphicDelegateProvider
<_BaseClass,
_Res
(
_ArgTypes
...)>(
ClassType
* object,
MemberType
member
)
717
: valueGetter(
718
[object,
member
](
_ArgTypes
&&... params) {
719
return
(object->*
member
)(std::forward<_ArgTypes>(params)...);
720
})
721
{}
722
727
template
<
typename
...Args>
728
PolymorphicDelegateProvider<_BaseClass,
_Res
(
_ArgTypes
...)>(
Args
&&... params)
729
: valueGetter(
std
::
forward
<
Args
>(params)...) {
730
}
731
737
_Res
operator()
(
_ArgTypes
... params)
const override
{
738
return
valueGetter(std::forward<_ArgTypes>(params)...);
739
}
740
};
741
742
};
//namespace plask
743
744
#endif
//PLASK__PROVIDER_H
plask
provider
provider.hpp
Generated by
1.9.8