1
0
forked from Alepha/Alepha

Add a bunch of TMP support.

I'm still on the fence about going full `constexpr` functions
for meta-code.  Overall, I think there's potential here.  I'm
not aiming to replicate what `boost::mpl` or `boost::hana` do
though.  This is more of an internal support mechanism for
Alepha code.  As-needed I'll implement things.
This commit is contained in:
2021-10-25 01:58:04 -04:00
parent 83aa3f9e61
commit 4538a8d943
4 changed files with 255 additions and 0 deletions

123
Meta/Container/vector.h Normal file
View File

@ -0,0 +1,123 @@
static_assert( __cplusplus > 201700, "C++17 Required" );
#pragma once
#include <Alepha/Alepha.h>
#include <Alepha/Meta/type_value.h>
namespace Alepha::Hydrogen::Meta::Container
{
inline namespace exports { inline namespace meta_container_vector {} }
namespace detail::meta_container_vector
{
inline namespace exports
{
template< typename ... Members > struct vector;
}
template< typename Vector >
struct vector_iterator
{
int offset= 0;
constexpr auto operator *() const;
constexpr vector_iterator &operator ++() { ++offset; return *this; }
constexpr vector_iterator operator++ ( int ) { auto rv= *this; ++offset; return rv; }
friend constexpr bool
operator == ( const vector_iterator &lhs, const vector_iterator &rhs )
{
return lhs.offset == rhs.offset;
}
friend constexpr bool
operator != ( const vector_iterator &lhs, const vector_iterator &rhs )
{
return lhs.offset != rhs.offset;
}
};
template< typename List >
struct dereferenced_iterator
{
vector_iterator< List > iter;
};
template< typename First, typename ... Members, typename Value >
constexpr bool
operator == ( const dereferenced_iterator< vector< First, Members... > > deref, type_value< Value > value )
{
if( deref.iter.offset == 0 ) return type_value< First >{} == value;
else return dereferenced_iterator< vector< Members... > >{ deref.iter.offset - 1 } == value;
}
template< typename Value >
constexpr bool
operator == ( const dereferenced_iterator< vector<> > iter, type_value< Value > value )
{
return false;
}
template< typename Vector >
constexpr auto
vector_iterator< Vector >::operator *() const
{
return dereferenced_iterator< Vector >{ *this };
}
template< typename ... Members >
struct exports::vector
{
using iterator= vector_iterator< vector >;
using const_iterator= vector_iterator< vector >;
constexpr auto begin() const { return vector_iterator< vector >{}; }
constexpr auto end() const { return vector_iterator< vector >{ sizeof...( Members ) }; }
template< typename Type >
[[nodiscard]] constexpr auto
push_back( type_value< Type > ) const
{
return vector< Members..., Type >{};
}
template< typename Type >
[[nodiscard]] constexpr auto
push_front( type_value< Type > ) const
{
return vector< Type, Members... >{};
}
[[nodiscard]] constexpr auto
clear() const
{
return vector<>{};
}
constexpr bool empty() const { return size() == 0; }
constexpr bool size() const { return sizeof...( Members ); }
};
template< typename ... LhsMembers, typename ... RhsMembers >
constexpr bool
operator == ( const vector< LhsMembers... > &lhs, const vector< RhsMembers... > &rhs )
{
return make_value_type( lhs ) == make_value_type( rhs );
}
template< typename ... LhsMembers, typename ... RhsMembers >
constexpr bool
operator != ( const vector< LhsMembers... > &lhs, const vector< RhsMembers... > &rhs )
{
return make_value_type( lhs ) != make_value_type( rhs );
}
}
namespace exports::meta_container_vector
{
using namespace detail::meta_container_vector::exports;
}
}