@@ -38,8 +38,8 @@ class ofAbstractParameter {
38
38
virtual std::string getEscapedName () const ;
39
39
virtual std::string valueType () const = 0;
40
40
41
- virtual bool isInit () const = 0;
42
- virtual void reInit () = 0 ;
41
+ virtual bool isInit () const { return true ; }
42
+ virtual void reInit () {} ;
43
43
44
44
virtual void setParent (ofParameterGroup & _parent) = 0;
45
45
std::vector<std::string> getGroupHierarchyNames () const ;
@@ -351,6 +351,23 @@ ofReadOnlyParameter<ParameterType, Friend> & ofParameterGroup::getReadOnly(std::
351
351
/* ! \cond PRIVATE */
352
352
namespace of {
353
353
namespace priv {
354
+
355
+ template <typename T, typename U = T>
356
+ constexpr auto test_comparable (int ) -> decltype(std::declval<T>() == std::declval<U>(), std::true_type{});
357
+
358
+ template <typename T, typename U = T>
359
+ constexpr std::false_type test_comparable (...);
360
+
361
+ template <typename T>
362
+ struct is_comparable : decltype (test_comparable<T>(0 )) {};
363
+
364
+ template <typename T>
365
+ struct is_comparable <std::vector<T>> : is_comparable<T> {};
366
+
367
+ template <typename T>
368
+ constexpr bool is_comparable_v = is_comparable<T>::value;
369
+
370
+
354
371
// ----------------------------------------------------------------------
355
372
// Mechanism to provide min and max default values for types where it makes sense
356
373
template <typename T, bool B>
@@ -510,6 +527,9 @@ template <typename ParameterType>
510
527
class ofParameter : public ofAbstractParameter {
511
528
public:
512
529
530
+ // / \brief flag to opt-out of the isInit mechanism (in-complement to auto-detection of incomparability)
531
+ static inline bool init_opt_out { false };
532
+
513
533
// / \brief constructs a default ofParameter of type ParameterType
514
534
// / \tparam ParameterType the type of the Value held by the ofParameter
515
535
ofParameter ();
@@ -601,6 +621,8 @@ class ofParameter : public ofAbstractParameter {
601
621
void makeReferenceTo (ofParameter<ParameterType> & mom);
602
622
603
623
ofParameter<ParameterType> & operator =(const ofParameter<ParameterType> & v);
624
+
625
+ template <typename U = ParameterType, std::enable_if_t <!std::is_same_v<U, ofParameter<U>>, int > = 0 >
604
626
const ParameterType & operator =(const ParameterType & v);
605
627
606
628
template <typename U = ParameterType>
@@ -671,39 +693,38 @@ class ofParameter : public ofAbstractParameter {
671
693
protected:
672
694
private:
673
695
class Value {
696
+ auto init_init (ParameterType &v) {
697
+ if constexpr (of::priv::is_comparable_v<ParameterType>) {
698
+ if (!init_opt_out) init = v;
699
+ }
700
+ }
701
+
674
702
public:
675
703
Value ()
676
- : init(of::priv::TypeInfo<ParameterType>::min())
677
- , min(of::priv::TypeInfo<ParameterType>::min())
704
+ : min(of::priv::TypeInfo<ParameterType>::min())
678
705
, max(of::priv::TypeInfo<ParameterType>::max())
679
706
, bInNotify(false )
680
- , serializable(true ) { }
681
-
707
+ , serializable(true ) { init_init (min); }
682
708
Value (ParameterType v)
683
- : init(v)
684
- , value(v)
709
+ : value(v)
685
710
, min(of::priv::TypeInfo<ParameterType>::min())
686
711
, max(of::priv::TypeInfo<ParameterType>::max())
687
712
, bInNotify(false )
688
- , serializable(true ) { }
689
-
713
+ , serializable(true ) { init_init (v); }
690
714
Value (std::string name, ParameterType v)
691
715
: name(name)
692
- , init(v)
693
716
, value(v)
694
717
, min(of::priv::TypeInfo<ParameterType>::min())
695
718
, max(of::priv::TypeInfo<ParameterType>::max())
696
719
, bInNotify(false )
697
- , serializable(true ) { }
698
-
720
+ , serializable(true ) { init_init (v); }
699
721
Value (std::string name, ParameterType v, ParameterType min, ParameterType max)
700
722
: name(name)
701
- , init(v)
702
723
, value(v)
703
724
, min(min)
704
725
, max(max)
705
726
, bInNotify(false )
706
- , serializable(true ) { }
727
+ , serializable(true ) { init_init (v); }
707
728
708
729
std::string name;
709
730
ParameterType init, value, min, max;
@@ -762,9 +783,10 @@ inline ofParameter<ParameterType> & ofParameter<ParameterType>::operator=(const
762
783
}
763
784
764
785
template <typename ParameterType>
786
+ template <typename U, std::enable_if_t <!std::is_same_v<U, ofParameter<U>>, int >>
765
787
inline const ParameterType & ofParameter<ParameterType>::operator =(const ParameterType & v) {
766
788
set (v);
767
- return obj-> value ;
789
+ return * this ;
768
790
}
769
791
770
792
template <typename ParameterType>
@@ -891,7 +913,13 @@ ParameterType ofParameter<ParameterType>::getMax() const {
891
913
892
914
template <typename ParameterType>
893
915
void ofParameter<ParameterType>::setInit(const ParameterType & init) {
894
- obj->init = init;
916
+ if constexpr (of::priv::is_comparable_v<ParameterType>) {
917
+ if (!init_opt_out) {
918
+ obj->init = init;
919
+ return ;
920
+ }
921
+ }
922
+ ofLogWarning (" ofParameter::setInit" ) << " called on a non-comparable (or opted-out) type" ;
895
923
}
896
924
897
925
template <typename ParameterType>
@@ -901,12 +929,24 @@ ParameterType ofParameter<ParameterType>::getInit() const {
901
929
902
930
template <typename ParameterType>
903
931
bool ofParameter<ParameterType>::isInit() const {
904
- return obj->value == obj->init ;
932
+ if constexpr (of::priv::is_comparable_v<ParameterType>) {
933
+ if (!init_opt_out) {
934
+ return obj->value == obj->init ;
935
+ }
936
+ }
937
+ ofLogWarning (" ofParameter::isInit" ) << " called on a non-comparable (or opted-out) type => always true" ;
938
+ return true ;
905
939
}
906
940
907
941
template <typename ParameterType>
908
942
void ofParameter<ParameterType>::reInit() {
909
- setMethod (obj->init );
943
+ if constexpr (of::priv::is_comparable_v<ParameterType>) {
944
+ if (!init_opt_out) {
945
+ setMethod (obj->init );
946
+ return ;
947
+ }
948
+ }
949
+ ofLogWarning (" ofParameter::reInit" ) << " called on a non-comparable (or opted-out) type => no-op" ;
910
950
}
911
951
912
952
template <typename ParameterType>
@@ -1276,9 +1316,6 @@ class ofReadOnlyParameter : public ofAbstractParameter {
1276
1316
1277
1317
void setMin (const ParameterType & min);
1278
1318
void setMax (const ParameterType & max);
1279
- void setInit (const ParameterType & init);
1280
- bool isInit () const ;
1281
- void reInit ();
1282
1319
1283
1320
void fromString (const std::string & str);
1284
1321
@@ -1560,27 +1597,6 @@ inline void ofReadOnlyParameter<ParameterType, Friend>::setMax(const ParameterTy
1560
1597
parameter.setMax (max);
1561
1598
}
1562
1599
1563
- template <typename ParameterType, typename Friend>
1564
- inline void ofReadOnlyParameter<ParameterType, Friend>::setInit(const ParameterType & init) {
1565
- parameter.setInit (init);
1566
- }
1567
-
1568
- template <typename ParameterType, typename Friend>
1569
- inline bool ofReadOnlyParameter<ParameterType, Friend>::isInit() const {
1570
- // not sure what the expected behaviour for isInit() would be for ReadOnlyParameter
1571
- // as-is, it fails with : No member named 'value' in 'ofParameter<std::string>'
1572
- // returning true while informing with a log msg seems sane
1573
- ofLogVerbose (" ofReadOnlyParameter::isInit()" ) << " isInit() called on ofReadOnlyParameter, where it always returns true" ;
1574
- return true ;
1575
- }
1576
-
1577
- template <typename ParameterType, typename Friend>
1578
- inline void ofReadOnlyParameter<ParameterType, Friend>::reInit() {
1579
- // not sure what the expected behaviour for reInit() would be for ReadOnlyParameter
1580
- // informing with a log msg seems sane
1581
- ofLogVerbose (" ofReadOnlyParameter::reInit()" ) << " reInit() called on ofReadOnlyParameter, where it is a no-op" ;
1582
- }
1583
-
1584
1600
template <typename ParameterType, typename Friend>
1585
1601
inline void ofReadOnlyParameter<ParameterType, Friend>::fromString(const std::string & str) {
1586
1602
parameter.fromString (str);
0 commit comments