Remove Pointer Attribute

Viewed 151

I have:

template<typename T>
struct is_objective_c_type {
private:
  // Removes all pointer indirection.
  // object*** => object
  // object**  => object
  // object*   => object

  template<class U> struct remove_pointer                    {typedef U type;};
  template<class U> struct remove_pointer<U*>                {typedef typename remove_pointer<U>::type type;};
  template<class U> struct remove_pointer<U* const>          {typedef typename remove_pointer<U>::type type;};
  template<class U> struct remove_pointer<U* volatile>       {typedef typename remove_pointer<U>::type type;};
  template<class U> struct remove_pointer<U* const volatile> {typedef typename remove_pointer<U>::type type;};
  
public:
  static const bool value = std::is_base_of<NSObject, typename remove_pointer<T>::type>::value;
};

and currently it works like:

@interface Foo: NSObject
@end

@implementation Foo
@end

is_objective_c_type<Foo>;  // true
is_objective_c_type<Foo*>;  // true
is_objective_c_type<Foo* __weak>; // false
is_objective_c_type<Foo* const*>;  // true

As you can see, it fails if I add the __weak attribute. However, if I change the template of remove_pointer to:

template<class U> 
struct remove_pointer<U* __weak>
{
    typedef typename remove_pointer<U>::type type;
};

It'll work. But that means it will never work for Foo* because it is implicitly __unsafe_unretained and it also won't work for Foo* __strong.

Currently it will give me ambiguous specialization if I define multiple:

template<class U> 
struct remove_pointer<U* __weak> { .. };

template<class U> 
struct remove_pointer<U* __unsafe_unretained> { .. };

template<class U> 
struct remove_pointer<U* __strong> { .. };

Is there a way to remove the ownership OR to specialize the template to work with the different ownerships?

1 Answers

I ended up doing:

template<typename T>
struct is_objective_c_type {
private:
  template<class U> struct remove_pointer                    {typedef U type;};
  template<class U> struct remove_pointer<U*>                {typedef typename remove_pointer<U>::type type;};
  template<class U> struct remove_pointer<U* const>          {typedef typename remove_pointer<U>::type type;};
  template<class U> struct remove_pointer<U* volatile>       {typedef typename remove_pointer<U>::type type;};
  template<class U> struct remove_pointer<U* const volatile> {typedef typename remove_pointer<U>::type type;};
  
public:
  static const bool value = std::is_base_of<NSObject, typename remove_pointer<T>::type>::value ||
                            std::is_convertible<typename remove_pointer<T>::type, NSObject*>::value;
};

as it is the only thing that seems to work for __weak, __strong, __unsafe_unretained, etc.

Related