+ operator T() const { return value<T>(); }
+
+private:
+ static bool type_equals(const Functions *, const Functions *);
+
+ template<typename T>
+ static constexpr bool is_small() { return (sizeof(T)<=INTERNAL_SIZE && alignof(T)<=alignof(void *)); }
+
+ template<typename T, typename U>
+ using EnableSmall = typename std::enable_if<is_small<T>(), U>::type;
+
+ template<typename T, typename U>
+ using EnableLarge = typename std::enable_if<!is_small<T>(), U>::type;
+
+ template<typename T>
+ static const Functions *get_functions();
+
+ template<typename T>
+ static const std::type_info &get_type() { return typeid(T); }
+
+ template<typename T>
+ static EnableSmall<T, void> create(char *s, T &&v)
+ { new(s) typename std::remove_reference<T>::type(std::forward<T>(v)); }
+
+ template<typename T>
+ static EnableLarge<T, void> create(char *s, T &&v)
+ { using V = typename std::remove_reference<T>::type; *reinterpret_cast<V **>(s) = new V(std::forward<T>(v)); }
+
+ template<typename T>
+ static typename std::enable_if<!IsEqualityComparable<T>::value, bool>::type compare(const char *, const char *)
+ { return false; }
+
+ template<typename T>
+ static typename std::enable_if<IsEqualityComparable<T>::value, EnableSmall<T, bool>>::type compare(const char *s1, const char *s2)
+ { return *reinterpret_cast<const T *>(s1)==*reinterpret_cast<const T *>(s2); }
+
+ template<typename T>
+ static typename std::enable_if<IsEqualityComparable<T>::value, EnableLarge<T, bool>>::type compare(const char *s1, const char *s2)
+ { return **reinterpret_cast<const T *const *>(s1)==**reinterpret_cast<const T *const *>(s2); }