Skip to content

Commit 1f32f8a

Browse files
RESTProcessBase::getClassdescObject now handled const types.
Fixed weak_ptr implementation of above.
1 parent 8dc3691 commit 1f32f8a

File tree

2 files changed

+71
-41
lines changed

2 files changed

+71
-41
lines changed

Diff for: RESTProcess_base.h

+24-6
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ namespace classdesc
2727
{
2828
protected:
2929
/// implementation of upcasting to a classdesc::object
30-
template <class T> typename enable_if<is_base_of<object,T>, object*>::T
30+
template <class T> typename enable_if<is_base_of<object,T>, const object*>::T
3131
getClassdescObjectImpl(T& obj) {return &obj;}
32-
template <class T> typename enable_if<Not<is_base_of<object,T>>, object*>::T
32+
template <class T> typename enable_if<Not<is_base_of<object,T>>, const object*>::T
3333
getClassdescObjectImpl(T& obj) {return nullptr;}
3434
public:
3535
virtual ~RESTProcessBase() {}
@@ -45,8 +45,10 @@ namespace classdesc
4545
template <class F> REST_PROCESS_BUFFER functionSignature() const;
4646
/// returns a pointer to the underlying object if it is one of type T, otherwise null
4747
template <class T> T* getObject();
48-
/// returns a classdesc object is referring to an object derived from classdesc::object
48+
/// @{ returns a classdesc object is referring to an object derived from classdesc::object
4949
virtual object* getClassdescObject() {return nullptr;}
50+
virtual const object* getConstClassdescObject() {return nullptr;}
51+
/// @}
5052
/// true if this is an object, not a function
5153
virtual bool isObject() const {return false;}
5254
/// true if this is a const object, a const member function or static/free function
@@ -334,7 +336,11 @@ namespace classdesc
334336
REST_PROCESS_BUFFER signature() const override;
335337
REST_PROCESS_BUFFER list() const override;
336338
REST_PROCESS_BUFFER type() const override {return REST_PROCESS_BUFFER(typeName<T>());}
337-
object* getClassdescObject() override {return getClassdescObjectImpl(obj);}
339+
object* getClassdescObject() override {
340+
if (is_const<T>::value) return nullptr;
341+
return const_cast<object*>(getClassdescObjectImpl(obj));
342+
}
343+
const object* getConstClassdescObject() override {return getClassdescObjectImpl(obj);}
338344
bool isObject() const override {return true;}
339345
bool isConst() const override {return std::is_const<T>::value;}
340346
};
@@ -721,7 +727,11 @@ namespace classdesc
721727
return REST_PROCESS_BUFFER(json5_parser::mArray());
722728
}
723729
REST_PROCESS_BUFFER type() const override {return REST_PROCESS_BUFFER(typeName<T>());}
724-
object* getClassdescObject() override {return ptr? getClassdescObjectImpl(*ptr): nullptr;}
730+
object* getClassdescObject() override {
731+
if (!ptr || is_const<typename T::element_type>::value) return nullptr;
732+
return const_cast<object*>(getClassdescObjectImpl(*ptr));
733+
}
734+
const object* getConstClassdescObject() override {return ptr? getClassdescObjectImpl(*ptr): nullptr;}
725735
};
726736

727737
template <class T>
@@ -737,7 +747,15 @@ namespace classdesc
737747
else return REST_PROCESS_BUFFER(json5_parser::mArray());
738748
}
739749
REST_PROCESS_BUFFER type() const override {return REST_PROCESS_BUFFER(typeName<std::weak_ptr<T> >());}
740-
object* getClassdescObject() override {return ptr? getClassdescObjectImpl(*ptr): nullptr;}
750+
object* getClassdescObject() override {
751+
auto p=ptr.lock();
752+
if (!p || is_const<typename T::element_type>::value) return nullptr;
753+
return const_cast<object*>(getClassdescObjectImpl(*p));
754+
}
755+
const object* getConstClassdescObject() override {
756+
auto p=ptr.lock();
757+
return p? getClassdescObjectImpl(*p): nullptr;
758+
}
741759
};
742760

743761

Diff for: classdesc.h

+47-35
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,13 @@ namespace classdesc
266266
template <class T> struct enable_if_c<false,T> {};
267267
/// controlled template specialisation: stolen from boost::enable_if.
268268
/**
269-
\a Cond is a condition class inheriting from \c
270-
std::tr1::true_type or std::tr1::false_type
269+
\a Cond is a condition class inheriting from \c
270+
std::tr1::true_type or std::tr1::false_type
271271
*/
272272
template <class Cond, class T=void> struct enable_if:
273273
public enable_if_c<Cond::value,T> {};
274274

275-
#undef True
275+
#undef True
276276
// NB - implementation of C++11 std::conditional
277277
template <bool C, class True, class F>
278278
struct conditional
@@ -316,7 +316,7 @@ namespace classdesc
316316
template <class K, class V, class C, class A>
317317
struct is_associative_container<std::map<K,V,C,A> > {
318318
static const bool value=true;};
319-
template <class T, class C, class A>
319+
template <class T, class C, class A>
320320
struct is_associative_container<std::multiset<T,C,A> > {
321321
static const bool value=true;};
322322
template <class K, class V, class C, class A>
@@ -348,7 +348,7 @@ namespace classdesc
348348
/// determines if T is a container
349349
template <class T> struct is_container {
350350
static const bool value=
351-
is_sequence<T>::value||is_associative_container<T>::value;
351+
is_sequence<T>::value||is_associative_container<T>::value;
352352
};
353353

354354
/// true_type if T is a StringKeyMap
@@ -418,16 +418,28 @@ namespace classdesc
418418
{static const bool value=X==Y;};
419419
///@}
420420

421+
/// transfer the constness property of T to U
422+
template <class T, class U, bool c=std::is_const<T>::value> struct transfer_const;
423+
template <class T, class U> struct transfer_const<T,U,true>
424+
{
425+
typedef typename std::add_const<U>::type type;
426+
};
427+
428+
template <class T, class U> struct transfer_const<T,U,false>
429+
{
430+
typedef typename std::remove_const<U>::type type;
431+
};
432+
421433
/// utility macro for declaring if a type has a particular member of
422434
/// type \a Sig
423-
#define CLASSDESC_HAS_MEMBER(mem) \
424-
template <class T, class Sig> \
425-
struct has_member_##mem \
426-
{ \
427-
template <class U, Sig> struct SFINAE {}; \
428-
template <class U> static char test(SFINAE<U,&U::mem>*); \
429-
template <class U> static int test(...); \
430-
const static bool value=sizeof(test<T>(0))==sizeof(char); \
435+
#define CLASSDESC_HAS_MEMBER(mem) \
436+
template <class T, class Sig> \
437+
struct has_member_##mem \
438+
{ \
439+
template <class U, Sig> struct SFINAE {}; \
440+
template <class U> static char test(SFINAE<U,&U::mem>*); \
441+
template <class U> static int test(...); \
442+
const static bool value=sizeof(test<T>(0))==sizeof(char); \
431443
};
432444

433445
// handle resize on nonresizable containers such as std::array
@@ -467,21 +479,21 @@ namespace classdesc
467479

468480

469481

470-
// template <class T>
471-
// typename enable_if<is_sequence<T>,void>::T
472-
// resize(T& x, std::size_t n) {x.resize(n);}
473-
//#if defined(__cplusplus) && __cplusplus>=201103L
474-
// template <class T, std::size_t N>
475-
// void resize(std::array<T,N>& x, std::size_t n) {}
476-
//#endif
482+
// template <class T>
483+
// typename enable_if<is_sequence<T>,void>::T
484+
// resize(T& x, std::size_t n) {x.resize(n);}
485+
//#if defined(__cplusplus) && __cplusplus>=201103L
486+
// template <class T, std::size_t N>
487+
// void resize(std::array<T,N>& x, std::size_t n) {}
488+
//#endif
477489

478490

479491
/// has default constructor, and is copiable
480492

481493
// is_assignable doesn't seem to be working correctly yet
482-
// template <class T> struct is_dca:
483-
// public And<And<is_default_constructible<T>, is_copy_constructible<T> >,
484-
// is_assignable<T,T> > {};
494+
// template <class T> struct is_dca:
495+
// public And<And<is_default_constructible<T>, is_copy_constructible<T> >,
496+
// is_assignable<T,T> > {};
485497
template <class T> struct is_dca:
486498
public And<is_default_constructible<T>, is_copy_constructible<T> > {};
487499

@@ -502,7 +514,7 @@ namespace classdesc
502514

503515
template <class T> struct is_rvalue<const T&>: public is_rvalue<T> {};
504516

505-
/// @}
517+
/// @}
506518

507519
/// base class for exceptions thrown by classdesc
508520
struct exception: std::runtime_error
@@ -513,13 +525,13 @@ namespace classdesc
513525
#if defined(__cplusplus) && __cplusplus>=201103L
514526
template <class Tp, class EqualTo>
515527
struct has_equality_operator_impl
516-
{
517-
template <class U, class V>
518-
static auto test(U*) -> decltype(std::declval<U>() == std::declval<V>());
519-
template <typename, typename>
520-
static auto test(...) -> std::false_type;
521-
using type=typename std::is_same<bool, decltype(test<Tp, EqualTo>(0))>::type;
522-
};
528+
{
529+
template <class U, class V>
530+
static auto test(U*) -> decltype(std::declval<U>() == std::declval<V>());
531+
template <typename, typename>
532+
static auto test(...) -> std::false_type;
533+
using type=typename std::is_same<bool, decltype(test<Tp, EqualTo>(0))>::type;
534+
};
523535
template <class T, class EqualTo=T>
524536
struct has_equality_operator: public has_equality_operator_impl<T,EqualTo>::type {};
525537

@@ -535,15 +547,15 @@ namespace classdesc
535547
template <class T>
536548
typename enable_if<
537549
And<Not<is_function<T> >, Not<is_member_function_pointer<T> > >,
538-
std::string>::T typeName();
550+
std::string>::T typeName();
539551

540552
#if defined(__cplusplus) && __cplusplus>=201103L
541553
// handle variadic arguments
542554
template <class T, class... A> std::string varTn() {return typeName<T>()+","+varTn<A...>();}
543555
template <class T> std::string varTn() {return typeName<T>();}
544556
#endif
545557

546-
///@{ a string representation of the type
558+
///@{ a string representation of the type
547559
template <> inline std::string typeName<void>() {return "void";}
548560
template <> inline std::string typeName<bool>() {return "bool";}
549561
template <> inline std::string typeName<char>() {return "char";}
@@ -644,7 +656,7 @@ namespace classdesc
644656
};
645657
#endif
646658

647-
template <class T,class A> struct tn<std::vector<T,A> >
659+
template <class T,class A> struct tn<std::vector<T,A> >
648660
{
649661
static std::string name()
650662
{return "std::vector<"+typeName<T>()+">";}
@@ -1002,7 +1014,7 @@ namespace classdesc
10021014
typename enable_if<is_integral<U>,const T*>::T
10031015
operator+(U x) const {return val+x;}
10041016
std::ptrdiff_t operator-(const T* x) const {return val-x;}
1005-
};
1017+
};
10061018

10071019
template <class T, class U>
10081020
typename enable_if<is_integral<U>,T*>::T

0 commit comments

Comments
 (0)