From ec07dcc83abb729100d2ea320a0cb1eb57cc7284 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Thu, 1 Jul 2021 22:28:24 -0400 Subject: [PATCH] Added Sequence and optional detection. This is part of the larger `Meta` library. Need to implement tuple-for-each and more. --- Meta/Makefile | 3 ++ Meta/is_deque.h | 34 +++++++++++++ Meta/is_forward_list.h | 34 +++++++++++++ Meta/is_list.h | 34 +++++++++++++ Meta/is_optional.h | 34 +++++++++++++ Meta/is_sequence.h | 36 +++++++++++++ Meta/is_string.h | 34 +++++++++++++ Meta/is_vector.h | 34 +++++++++++++ Meta/test.cc | 112 +++++++++++++++++++++++++++++++++++++++++ 9 files changed, 355 insertions(+) create mode 100644 Meta/Makefile create mode 100644 Meta/is_deque.h create mode 100644 Meta/is_forward_list.h create mode 100644 Meta/is_list.h create mode 100644 Meta/is_optional.h create mode 100644 Meta/is_sequence.h create mode 100644 Meta/is_string.h create mode 100644 Meta/is_vector.h create mode 100644 Meta/test.cc diff --git a/Meta/Makefile b/Meta/Makefile new file mode 100644 index 0000000..3ec6ce7 --- /dev/null +++ b/Meta/Makefile @@ -0,0 +1,3 @@ +CXXFLAGS+= -std=c++17 -I ../ + +all: test diff --git a/Meta/is_deque.h b/Meta/is_deque.h new file mode 100644 index 0000000..c2018e1 --- /dev/null +++ b/Meta/is_deque.h @@ -0,0 +1,34 @@ +static_assert( __cplusplus > 201700, "C++17 Required" ); + +#pragma once + +#include + +#include +#include + +namespace Alepha::Hydrogen::Meta +{ + inline namespace exports { inline namespace type_traits {} } + + namespace detail::type_traits::is_deque + { + inline namespace exports + { + template< typename T > + struct is_deque : std::false_type {}; + + template< typename T, typename ... Args > + struct is_deque< std::deque< T, Args... > > : std::true_type {}; + + template< typename T > + constexpr bool is_deque_v= is_deque< T >::value; + } + } + + namespace exports::type_traits + { + using namespace detail::type_traits::is_deque::exports; + } +} + diff --git a/Meta/is_forward_list.h b/Meta/is_forward_list.h new file mode 100644 index 0000000..85d191e --- /dev/null +++ b/Meta/is_forward_list.h @@ -0,0 +1,34 @@ +static_assert( __cplusplus > 201700, "C++17 Required" ); + +#pragma once + +#include + +#include +#include + +namespace Alepha::Hydrogen::Meta +{ + inline namespace exports { inline namespace type_traits {} } + + namespace detail::type_traits::is_forward_list + { + inline namespace exports + { + template< typename T > + struct is_forward_list : std::false_type {}; + + template< typename T, typename ... Args > + struct is_forward_list< std::forward_list< T, Args... > > : std::true_type {}; + + template< typename T > + constexpr bool is_forward_list_v= is_forward_list< T >::value; + } + } + + namespace exports::type_traits + { + using namespace detail::type_traits::is_forward_list::exports; + } +} + diff --git a/Meta/is_list.h b/Meta/is_list.h new file mode 100644 index 0000000..c1ed0e4 --- /dev/null +++ b/Meta/is_list.h @@ -0,0 +1,34 @@ +static_assert( __cplusplus > 201700, "C++17 Required" ); + +#pragma once + +#include + +#include +#include + +namespace Alepha::Hydrogen::Meta +{ + inline namespace exports { inline namespace type_traits {} } + + namespace detail::type_traits::is_list + { + inline namespace exports + { + template< typename T > + struct is_list : std::false_type {}; + + template< typename T, typename ... Args > + struct is_list< std::list< T, Args... > > : std::true_type {}; + + template< typename T > + constexpr bool is_list_v= is_list< T >::value; + } + } + + namespace exports::type_traits + { + using namespace detail::type_traits::is_list::exports; + } +} + diff --git a/Meta/is_optional.h b/Meta/is_optional.h new file mode 100644 index 0000000..3e9b2e3 --- /dev/null +++ b/Meta/is_optional.h @@ -0,0 +1,34 @@ +static_assert( __cplusplus > 201700, "C++17 Required" ); + +#pragma once + +#include + +#include +#include + +namespace Alepha::Hydrogen::Meta +{ + inline namespace exports { inline namespace type_traits {} } + + namespace detail::type_traits::is_optional + { + inline namespace exports + { + template< typename T > + struct is_optional : std::false_type {}; + + template< typename T, typename ... Args > + struct is_optional< std::optional< T, Args... > > : std::true_type {}; + + template< typename T > + constexpr bool is_optional_v= is_optional< T >::value; + } + } + + namespace exports::type_traits + { + using namespace detail::type_traits::is_optional::exports; + } + +} diff --git a/Meta/is_sequence.h b/Meta/is_sequence.h new file mode 100644 index 0000000..2fd0443 --- /dev/null +++ b/Meta/is_sequence.h @@ -0,0 +1,36 @@ +static_assert( __cplusplus > 201700, "C++17 Required" ); + +#pragma once + +#include + +#include + +#include +#include +#include +#include +#include + +namespace Alepha::Hydrogen::Meta +{ + inline namespace exports { inline namespace type_traits {} } + + namespace detail::type_traits::is_sequence + { + inline namespace exports + { + template< typename T > + constexpr bool is_sequence_v= is_list_v< T > or is_forward_list_v< T > or is_deque_v< T > or is_string_v< T > or is_vector_v< T >; + + template< typename T > + struct is_sequence : std::bool_constant< is_sequence_v< T > > {}; + } + } + + namespace exports::type_traits + { + using namespace detail::type_traits::is_sequence::exports; + } +} + diff --git a/Meta/is_string.h b/Meta/is_string.h new file mode 100644 index 0000000..913a445 --- /dev/null +++ b/Meta/is_string.h @@ -0,0 +1,34 @@ +static_assert( __cplusplus > 201700, "C++17 Required" ); + +#pragma once + +#include + +#include +#include + +namespace Alepha::Hydrogen::Meta +{ + inline namespace exports { inline namespace type_traits {} } + + namespace detail::type_traits::is_string + { + inline namespace exports + { + template< typename T > + struct is_string : std::false_type {}; + + template< typename T, typename ... Args > + struct is_string< std::basic_string< T, Args... > > : std::true_type {}; + + template< typename T > + constexpr bool is_string_v= is_string< T >::value; + } + } + + namespace exports::type_traits + { + using namespace detail::type_traits::is_string::exports; + } +} + diff --git a/Meta/is_vector.h b/Meta/is_vector.h new file mode 100644 index 0000000..57fb0d7 --- /dev/null +++ b/Meta/is_vector.h @@ -0,0 +1,34 @@ +static_assert( __cplusplus > 201700, "C++17 Required" ); + +#pragma once + +#include + +#include +#include + +namespace Alepha::Hydrogen::Meta +{ + inline namespace exports { inline namespace type_traits {} } + + namespace detail::type_traits::is_vector + { + inline namespace exports + { + template< typename T > + struct is_vector : std::false_type {}; + + template< typename T, typename ... Args > + struct is_vector< std::vector< T, Args... > > : std::true_type {}; + + template< typename T > + constexpr bool is_vector_v= is_vector< T >::value; + } + } + + namespace exports::type_traits + { + using namespace detail::type_traits::is_vector::exports; + } +} + diff --git a/Meta/test.cc b/Meta/test.cc new file mode 100644 index 0000000..519f2b0 --- /dev/null +++ b/Meta/test.cc @@ -0,0 +1,112 @@ +static_assert( __cplusplus > 201700, "C++17 Required" ); + +#include + +#include + +#include + +#include + +int +main( const int argcnt, const char *const *const argvec ) +{ + return Alepha::Testing::runAllTests( argcnt, argvec ); +} + +namespace +{ + using namespace Alepha::Utility::evaluation; + using namespace Alepha::Testing::literals; + + // These tests never actually fail at runtime, but they provide a simple way to have them + // as unit tests. There's no call to actually assert them at runtime. If this test built, + // it passes. + auto tests= enroll <=[] + { + "meta.specific"_test <=[] + { + static_assert( Alepha::Meta::is_vector_v< std::vector< int > > ); + static_assert( Alepha::Meta::is_list_v< std::list< int > > ); + static_assert( Alepha::Meta::is_forward_list_v< std::forward_list< int > > ); + static_assert( Alepha::Meta::is_deque_v< std::deque< int > > ); + + static_assert( Alepha::Meta::is_vector_v< std::vector< std::string > > ); + static_assert( Alepha::Meta::is_list_v< std::list< std::string > > ); + static_assert( Alepha::Meta::is_forward_list_v< std::forward_list< std::string > > ); + static_assert( Alepha::Meta::is_deque_v< std::deque< std::string > > ); + + static_assert( Alepha::Meta::is_string_v< std::string > ); + static_assert( Alepha::Meta::is_string_v< std::wstring > ); + }; + + "meta.sequence"_test <=[] + { + static_assert( Alepha::Meta::is_sequence_v< std::vector< int > > ); + static_assert( Alepha::Meta::is_sequence_v< std::list< int > > ); + static_assert( Alepha::Meta::is_sequence_v< std::forward_list< int > > ); + static_assert( Alepha::Meta::is_sequence_v< std::deque< int > > ); + + static_assert( Alepha::Meta::is_sequence_v< std::vector< std::string > > ); + static_assert( Alepha::Meta::is_sequence_v< std::list< std::string > > ); + static_assert( Alepha::Meta::is_sequence_v< std::forward_list< std::string > > ); + static_assert( Alepha::Meta::is_sequence_v< std::deque< std::string > > ); + + static_assert( Alepha::Meta::is_sequence_v< std::string > ); + static_assert( Alepha::Meta::is_sequence_v< std::wstring > ); + }; + + "meta.confusion"_test <=[] + { + static_assert( not Alepha::Meta::is_sequence_v< int > ); + static_assert( not Alepha::Meta::is_sequence_v< std::nullptr_t > ); + + static_assert( not Alepha::Meta::is_vector_v< std::list< int > > ); + static_assert( not Alepha::Meta::is_vector_v< std::forward_list< int > > ); + static_assert( not Alepha::Meta::is_vector_v< std::deque< int > > ); + static_assert( not Alepha::Meta::is_vector_v< std::list< std::string > > ); + static_assert( not Alepha::Meta::is_vector_v< std::forward_list< std::string > > ); + static_assert( not Alepha::Meta::is_vector_v< std::deque< std::string > > ); + static_assert( not Alepha::Meta::is_vector_v< std::string > ); + static_assert( not Alepha::Meta::is_vector_v< std::wstring > ); + + static_assert( not Alepha::Meta::is_list_v< std::vector< int > > ); + static_assert( not Alepha::Meta::is_list_v< std::forward_list< int > > ); + static_assert( not Alepha::Meta::is_list_v< std::deque< int > > ); + static_assert( not Alepha::Meta::is_list_v< std::vector< std::string > > ); + static_assert( not Alepha::Meta::is_list_v< std::forward_list< std::string > > ); + static_assert( not Alepha::Meta::is_list_v< std::deque< std::string > > ); + static_assert( not Alepha::Meta::is_list_v< std::string > ); + static_assert( not Alepha::Meta::is_list_v< std::wstring > ); + + static_assert( not Alepha::Meta::is_forward_list_v< std::vector< int > > ); + static_assert( not Alepha::Meta::is_forward_list_v< std::list< int > > ); + static_assert( not Alepha::Meta::is_forward_list_v< std::deque< int > > ); + static_assert( not Alepha::Meta::is_forward_list_v< std::vector< std::string > > ); + static_assert( not Alepha::Meta::is_forward_list_v< std::list< std::string > > ); + static_assert( not Alepha::Meta::is_forward_list_v< std::deque< std::string > > ); + static_assert( not Alepha::Meta::is_forward_list_v< std::string > ); + static_assert( not Alepha::Meta::is_forward_list_v< std::wstring > ); + + static_assert( not Alepha::Meta::is_deque_v< std::vector< int > > ); + static_assert( not Alepha::Meta::is_deque_v< std::list< int > > ); + static_assert( not Alepha::Meta::is_deque_v< std::forward_list< int > > ); + static_assert( not Alepha::Meta::is_deque_v< std::vector< std::string > > ); + static_assert( not Alepha::Meta::is_deque_v< std::list< std::string > > ); + static_assert( not Alepha::Meta::is_deque_v< std::forward_list< std::string > > ); + static_assert( not Alepha::Meta::is_deque_v< std::string > ); + static_assert( not Alepha::Meta::is_deque_v< std::wstring > ); + + static_assert( not Alepha::Meta::is_string_v< std::vector< int > > ); + static_assert( not Alepha::Meta::is_string_v< std::list< int > > ); + static_assert( not Alepha::Meta::is_string_v< std::forward_list< int > > ); + static_assert( not Alepha::Meta::is_string_v< std::deque< int > > ); + static_assert( not Alepha::Meta::is_string_v< std::vector< std::string > > ); + static_assert( not Alepha::Meta::is_string_v< std::list< std::string > > ); + static_assert( not Alepha::Meta::is_string_v< std::forward_list< std::string > > ); + static_assert( not Alepha::Meta::is_string_v< std::deque< std::string > > ); + }; + }; +} + +