Alternate list-initialization

#include <iostream>
#include <utility>
#include <vector>
#include <memory>

// 1. Implementing a variadic logical AND
template <bool...> struct bool_sequence {};
 
template <bool... Bs>
using bool_and
 = std::is_same<bool_sequence<Bs...>,
                bool_sequence<(Bs || true)...>>;
 
// 2. Helper function to test implicit conversion 
template <typename T>
  std::true_type create(T v);
 
// 3a. Test for conversion and non-narrowing
template <typename T, typename U>
  decltype(create<U>({std::declval<T>()})) // <- braces
  test_nonnarow_conv(int);
 
// 3b. Fallback function if sfinae fails on 3a
template <typename T, typename U>
  std::false_type test_nonnarow_conv(long);
 
// 3c. Single-argument conversion trait
template <typename T, typename U>
  using is_nonarrow_convertible
  = decltype(test_nonnarow_conv<T, U>(0));
 
// 4. Our multi-argument trait
template <typename T, typename... Ts>
  using nonarrow_convertible
  = bool_and<is_nonarrow_convertible<Ts, T>::value...>;

# define REQUIRES(...)                                      \
  typename std::enable_if<(__VA_ARGS__), bool>::type = true \
  
template <typename T>
class Vec
{ 
public:
    
  std::vector<T> _vect;
     
  template <typename... UList,
          REQUIRES(nonarrow_convertible<T, UList...>::value)>
  Vec(UList &&... vs)
  {
    _vect.reserve(sizeof...(vs));
    process(std::forward<UList>(vs)...); // decompose
  }
     
  template <typename U, typename... UList>
  void process(U && v, UList &&... vs)
  {
    _vect.push_back(std::forward<U>(v));
    process(std::forward<UList>(vs)...);
  }
     
  void process() {} // end recursion  
};

int main()
{
    Vec<int> v {1, 2, 3};
    Vec<int> u {};
    Vec<int> w {1, 2};
    Vec<std::unique_ptr<int>> pv { std::make_unique<int>(1),
                                   std::make_unique<int>(2) };
    
    std::cout << v._vect[0] << " "
              << v._vect[1] << " "
              << v._vect[2] << std::endl;
}