From 8c232df3753afe09f3433c3b07d1ef90a4a6c207 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Wed, 8 Jun 2022 15:24:44 +0200 Subject: [PATCH] assign sfinae is integral detection --- Makefile | 3 +- headers/enable_if.hpp | 16 ++++++ headers/is_integral.hpp | 116 ++++++++++++++++++++++++++++++++++++++++ headers/vector.hpp | 12 ++++- templates/vector.tpp | 14 +++-- 5 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 headers/enable_if.hpp create mode 100644 headers/is_integral.hpp diff --git a/Makefile b/Makefile index 4182658..db9cec5 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ RESET = "\e[0m" NAME = containers -CC = c++ +CC = clang++ EXT = cpp CFLAGS = -Wall -Wextra -Werror $(INCLUDES) @@ -55,6 +55,7 @@ SRCS = main.cpp D_HEADERS = ./headers HEADERS = colors.h \ tests.hpp \ + enable_if.hpp \ vector.hpp D_TEMPLATES = ./templates diff --git a/headers/enable_if.hpp b/headers/enable_if.hpp new file mode 100644 index 0000000..655ee96 --- /dev/null +++ b/headers/enable_if.hpp @@ -0,0 +1,16 @@ +#ifndef ENABLE_IF_HPP +# define ENABLE_IF_HPP + +namespace ft { + +template +struct enable_if {}; + + +template +struct enable_if { typedef T type; }; + +} // namespace ft + +#endif + diff --git a/headers/is_integral.hpp b/headers/is_integral.hpp new file mode 100644 index 0000000..e6cb782 --- /dev/null +++ b/headers/is_integral.hpp @@ -0,0 +1,116 @@ +#ifndef IS_INTEGRAL_HPP +# define IS_INTEGRAL_HPP + +namespace ft { + +//struct true_type { +// typedef bool value_type; +// typedef true_type type; +// static const bool value = true; +//}; +// +//struct false_type { +// typedef T value_type; +// typedef false_type type; +// static const bool value = false; +//}; + +template struct is_integral +{ + typedef char yes[1]; + typedef yes no[2]; + + static T type; + +// integral types : https://www.cplusplus.com/reference/type_traits/is_integral/ + static yes& test(bool); + static yes& test(char); +// static yes& test(char16_t); +// static yes& test(char32_t); + static yes& test(wchar_t); + static yes& test(signed char); + static yes& test(short int); + static yes& test(int); + static yes& test(long int); + static yes& test(long long int); + static yes& test(unsigned char); + static yes& test(unsigned short int); + static yes& test(unsigned int); + static yes& test(unsigned long int); + static yes& test(unsigned long long int); + +/* + static yes& test(const bool); + static yes& test(const char); + static yes& test(const wchar_t); + static yes& test(const signed char); + static yes& test(const short int); + static yes& test(const int); + static yes& test(const long int); + static yes& test(const long long int); + static yes& test(const unsigned char); + static yes& test(const unsigned short int); + static yes& test(const unsigned int); + static yes& test(const unsigned long int); + static yes& test(const unsigned long long int); + + static yes& test(volatile bool); + static yes& test(volatile char); + static yes& test(volatile wchar_t); + static yes& test(volatile signed char); + static yes& test(volatile short int); + static yes& test(volatile int); + static yes& test(volatile long int); + static yes& test(volatile long long int); + static yes& test(volatile unsigned char); + static yes& test(volatile unsigned short int); + static yes& test(volatile unsigned int); + static yes& test(volatile unsigned long int); + static yes& test(volatile unsigned long long int); + + static yes& test(const volatile bool); + static yes& test(const volatile char); + static yes& test(const volatile wchar_t); + static yes& test(const volatile signed char); + static yes& test(const volatile short int); + static yes& test(const volatile int); + static yes& test(const volatile long int); + static yes& test(const volatile long long int); + static yes& test(const volatile unsigned char); + static yes& test(const volatile unsigned short int); + static yes& test(const volatile unsigned int); + static yes& test(const volatile unsigned long int); + static yes& test(const volatile unsigned long long int); +*/ + + + // non-template function with direct matching are always considered first + // then the function template with direct matching are considered + // https://stackoverflow.com/questions/12877546/how-do-i-avoid-implicit-conversions-on + template static no& test(C); + + static const bool value = sizeof(test(type)) == sizeof(yes); +}; + +} // namespace ft + +// "template <>" introduce a total specialization of a template : +// +// template +// class A +// { +// // body for the general case +// }; +// +// template <> +// class A +// { +// // body that only applies for T = bool +// }; +// +// https://stackoverflow.com/questions/6288812/what-is-the-meaning-of-template-with-empty-angle-brackets-in-c + +// SFINAE : https://jguegant.github.io/blogs/tech/sfinae-introduction.html + +#endif + diff --git a/headers/vector.hpp b/headers/vector.hpp index 5e793cc..53ed939 100644 --- a/headers/vector.hpp +++ b/headers/vector.hpp @@ -4,9 +4,10 @@ # include "colors.h" # include # include - # include // std::allocator # include // std::min +# include "enable_if.hpp" +# include "is_integral.hpp" namespace ft { @@ -96,7 +97,14 @@ public: *************/ // assign ------------------------------------ template - void assign(InputIterator first, InputIterator last); + typename enable_if< !is_integral::value,void >::type + assign(InputIterator first, InputIterator last); + // template + // void assign(InputIterator first, InputIterator last + // typename enable_if< !is_integral::value, bool >::type == true); +// template +// typename enable_if< is_integral::value,void >::type +// assign(size_type n, const value_type& val); void assign(size_type n, const value_type& val); // push_back --------------------------------- void push_back(const value_type & val); diff --git a/templates/vector.tpp b/templates/vector.tpp index 0dde9e9..fe48257 100644 --- a/templates/vector.tpp +++ b/templates/vector.tpp @@ -171,10 +171,13 @@ VT_TPL typename VT::reference VT:: * modifiers : *************/ // assign ------------------------------------ -VT_TPL template void VT:: +VT_TPL template +typename enable_if< !is_integral::value,void >::type VT:: assign( InputIterator first, InputIterator last) { -std::cout << "inside assign(first, last)"; +// TMP +std::cout << B_RED "inside assign(first, last) " RESET; +// TMP END InputIterator tmp = first; int range; @@ -192,10 +195,15 @@ std::cout << "inside assign(first, last)"; } } +// VT_TPL typename enable_if< isinteger::value,std::string >::type VT:: +//VT_TPL template +//typename enable_if< is_integral::value,void >::type VT:: VT_TPL void VT:: assign( size_type n, const T & val ) { -std::cout << "inside assign(n, val)"; +// TMP +std::cout << B_RED "inside assign(n, val) " RESET; +// TMP END if (n > _allocator.max_size()) throw std::length_error("assign: n > max_size");