Your current solution is flawed for objects from the cppu namespace, e.g.
// [insert your code here]
namespace cppu
{
  struct X{};
  struct Y{ void swap(Y& y) { }; };
}
int main()
{
  auto x1 = cppu::X{};
  auto x2 = cppu::X{};
  swap(x1, x2);
  auto y1 = cppu::Y{};
  auto y2 = cppu::Y{};
  swap(y1, y2);
}
g++ tells me:
taste.cpp:9:7: error: call of overloaded ‘swap(cppu::X&, cppu::X&)’ is ambiguous
To get rid of this, you need to explicitly call std::swap in swap_impl, which is OK, since you arrived here through the cppu::swap implementation already. But then you do not use overloads for other types. Thus, I think you need to distinguish three cases:
- Has own swap member function
 
- Has no swap member function and is from namespace cppu
 
- Has no swap member function and is any other namespace (here you need to use the ADL swap idiom). 
 
Also, I concur with @Yakk that I would be more direct instead of using the int/char hack.
So let's go for it:
A helper for checking the availability of the swap member:
namespace cppu
{
  namespace detail
  { 
    template <typename T>
    using void_t = void;
    template <typename T, typename = void>
    struct has_member_swap
    {
      static constexpr bool value = false;
    };
    template <typename T>
    struct has_member_swap<
        T,
        void_t<decltype(std::declval<T&>().swap(std::declval<T&>()))>>
    {
      static constexpr bool value = true;
    };
  }
}
And a helper to check if T is from namespace cppu, see also here:
namespace helper
{
  template <typename T, typename = void>
  struct is_member_of_cppu : std::false_type
  {
  };
  template <typename T>
  struct is_member_of_cppu<
      T,
      decltype(adl_is_member_of_cppu(std::declval<T>()))> : std::true_type
  {
  };
}   
namespace cppu
{   
  template <typename T>
  auto adl_is_member_of_cppu(T && ) -> void;
}
Now we can write all three overloads:
namespace cppu
{
  namespace detail
  {
    template <
        typename T,
        typename = std::enable_if_t<helper::is_member_of_cppu<T>::value and
                                    not has_member_swap<T>::value>>
    auto swap(T& x, T& y) 
        -> std::enable_if_t<helper::is_member_of_cppu<T>::value and
                            not has_member_swap<T>::value>
    {
      std::cout << "cppu-type without member swap";
      std::swap(x, y);
    }
    template <
        typename T,
        typename = std::enable_if_t<not helper::is_member_of_cppu<T>::value and
                                    not has_member_swap<T>::value>>
    auto swap(T& x, T& y)
        -> std::enable_if_t<not helper::is_member_of_cppu<T>::value and
                            not has_member_swap<T>::value>
    {
      std::cout << "not cppu-type without member swap";
      using std::swap;
      swap(x, y);
    }
    template <typename T, typename = std::enable_if_t<has_member_swap<T>::value>>
    auto swap(T& x, T& y) -> decltype(x.swap(y))
    {
      std::cout << "member swap";
      return x.swap(y);
    }
  }
}
Call this as you did before:
namespace cppu
{
  template <typename T>
  void swap(T& x, T& y)
  {
    detail::swap(x, y);
  }   
}
And finally: Test the whole thing.
namespace cppu
{
  struct X{};
  struct Y{ void swap(Y& y) { }; };
}
struct A{};
struct B{ void swap(B& y) { }; };
struct C{};
auto swap(C&, C&) -> void { std::cout << " with own overload"; }
static_assert(helper::is_member_of_cppu<cppu::X>::value, "");
static_assert(helper::is_member_of_cppu<cppu::Y>::value, "");
static_assert(not helper::is_member_of_cppu<A>::value, "");
static_assert(not helper::is_member_of_cppu<B>::value, "");
int main()
{
  auto x1 = cppu::X{};
  auto x2 = cppu::X{};
  std::cout << "X: "; swap(x1, x2); std::cout << std::endl;
  auto y1 = cppu::Y{};
  auto y2 = cppu::Y{};
  std::cout << "Y: "; swap(y1, y2); std::cout << std::endl;
  auto a1 = A{};
  auto a2 = A{};
  std::cout << "A: "; cppu::swap(a1, a2); std::cout << std::endl;
  auto b1 = B{};
  auto b2 = B{};
  std::cout << "B: "; cppu::swap(b1, b2); std::cout << std::endl;
  auto c1 = C{};
  auto c2 = C{};
  std::cout << "C: "; cppu::swap(c1, c2); std::cout << std::endl;
}
The output is as expected (IMHO):
X: cppu-type without member swap 
  Y: member swap 
  A: not cppu-type without member swap 
  B: member swap 
  C: not cppu-type without member swap with own overload