1
0
forked from Alepha/Alepha

Merge remote-tracking branch 'side-line/master'

This commit is contained in:
2023-02-09 20:51:09 -08:00
3 changed files with 340 additions and 0 deletions

93
Meta/Container/string.h Normal file
View File

@ -0,0 +1,93 @@
static_assert( __cplusplus > 201700, "C++17 Required" );
#pragma once
#include <Alepha/Alepha.h>
#include <array>
#include <Alepha/comparisons.h>
#include <Alepha/Constexpr/algorithm.h>
#include <Alepha/Constexpr/array.h>
namespace Alepha::Hydrogen::Meta::Container
{
inline namespace exports { inline namespace meta_container_string {} }
namespace detail::meta_container_string
{
inline namespace exports {}
namespace C
{
const std::size_t amount= 4096;
}
namespace exports
{
template< typename CharT > class basic_string;
template< typename CharT, CharT ... text >
struct constexpr_str_wrapper
: comparable
{
#define MAKE_OP( op ) \
template< CharT ... text2 > \
constexpr friend bool \
operator op ( const constexpr_str_wrapper< CharT, text... > lhs, const constexpr_str_wrapper< CharT, text2... > rhs ) \
{ \
return basic_string< CharT >{ lhs } op basic_string< CharT >{ rhs }; \
}
MAKE_OP( < );
MAKE_OP( > );
MAKE_OP( <= );
MAKE_OP( >= );
MAKE_OP( == );
MAKE_OP( != );
#undef MAKE_OP
};
template< typename CharT >
class basic_string
: public comparable
{
private:
Constexpr::array< CharT, C::amount > raw;
public:
template< CharT ... text >
constexpr explicit
basic_string( constexpr_str_wrapper< CharT, text... > )
: raw()
{
CharT chars[]= { text..., '\0' };
using std::begin, std::end;
Constexpr::copy( begin( chars ), end( chars ), begin( raw ) );
}
constexpr auto value_lens() const noexcept { return ordering_magma( raw ); }
};
using string= basic_string< char >;
}
}
namespace exports::meta_container_string
{
using namespace detail::meta_container_string::exports;
}
}
template< typename CharT, CharT ... text >
struct Alepha::Meta::unique_for_type_binder< Alepha::Meta::type_value< Alepha::Meta::Container::constexpr_str_wrapper< CharT, text... > > >
{
static constexpr auto
build() noexcept
{
return Alepha::Meta::Container::basic_string{ Alepha::Meta::Container::constexpr_str_wrapper< CharT, text... >{} };
}
};

24
Meta/dep_value.h Normal file
View File

@ -0,0 +1,24 @@
static_assert( __cplusplus > 201700, "C++17 Required" );
#pragma once
#include <Alepha/Alepha.h>
namespace Alepha::Hydrogen::Meta
{
inline namespace exports { inline namespace dependent_value {} }
namespace detail::dependent_value
{
inline namespace exports
{
template< auto value, typename T >
constexpr auto dep_value= value;
}
}
namespace exports::dependent_value
{
using namespace detail::dependent_value::exports;
}
}

223
Meta/type_algorithm.h Normal file
View File

@ -0,0 +1,223 @@
static_assert( __cplusplus > 201700, "C++17 Required" );
#pragma once
#include <Alepha/Alepha.h>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <functional>
#include <Alepha/Constexpr/algorithm.h>
#include <Alepha/Constexpr/array.h>
#include <Alepha/Meta/Container/vector.h>
namespace Alepha::Hydrogen::Meta
{
inline namespace exports { inline namespace type_algorithm {} }
namespace detail::type_algorithm
{
inline namespace exports
{
template< typename T > struct unique_for_type_binder;
template< typename T > constexpr auto unique_for_type= unique_for_type_binder< T >::build();
}
using Container::vector;
template< typename, typename > struct type_less;
//template< typename A >
//struct type_less< A, A > : std::false_type {};
constexpr bool
char_string_less( const char *left, const char *right )
{
// std::cerr << "Comparing..." << std::endl;
// std::cerr << left << std::endl;
// std::cerr << right << std::endl;
while( *left and *right )
{
// std::cerr << "Comparing \"" << *left << "\" to \"" << *right << '"' << std::endl;
if( *left < *right ) return true;
if( *left > *right ) return false;
assert( *left == *right );
++left; ++right;
}
// std::cerr << "Ran out of chars..." << std::endl;
if( *left == *right ) return false;
if( *left ) return false;
return true;
}
constexpr bool
char_string_eq( const char *left, const char *right )
{
while( *left and *right )
{
if( *left++ != *right++ ) return false;
}
return *left == *right;
}
template< typename T >
constexpr const char *
single_type_value()
{
return __PRETTY_FUNCTION__;
}
template< typename A, typename B >
constexpr bool
compute()
{
return char_string_less( single_type_value< A >(), single_type_value< B >() );
}
template< typename A, typename B >
struct type_less
{
static const bool value= compute< A, B >();
};
template< typename A, typename B >
constexpr bool type_less_v= type_less< A, B >::value;
template< typename T >
constexpr void
constexpr_swap( T &a, T &b ) noexcept
{
T tmp= std::move( a );
a= std::move( b );
b= std::move( tmp );
}
template< typename Iter, typename Comp >
constexpr void
constexpr_sort( Iter first, Iter last, Comp comp )
{
if( first == last ) return;
const auto pos= std::min_element( first, last, comp );
using std::swap;
constexpr_swap( *pos, *first );
constexpr_sort( ++first, last, comp );
}
namespace exports
{
template< typename ... Types >
constexpr bool
all_unique() noexcept
{
std::array< const char *, sizeof...( Types ) > magic_values= { single_type_value< Types >()... };
using std::begin, std::end;
const std::size_t amt= magic_values.size();
if constexpr( amt <= 1 ) return true;
else
{
constexpr_sort( begin( magic_values ), end( magic_values ), &char_string_less );
for( auto pos= begin( magic_values ); pos < end( magic_values ) - 1; ++pos )
{
if( char_string_eq( *pos, *( pos + 1 ) ) ) return false;
}
return true;
}
}
}
template< typename ... Types >
struct lowest_type_impl;
template< typename Type >
struct lowest_type_impl< Type >
{
using type= Type;
};
template< typename Type, typename ... Types >
struct lowest_type_impl< Type, Types... >
{
using later_lowest= typename lowest_type_impl< Types... >::type;
using type= std::conditional_t
<
type_less_v< Type, later_lowest >,
Type,
later_lowest
>;
};
namespace exports
{
template< typename ... Types >
using lowest_type_t= typename lowest_type_impl< Types... >::type;
}
template< typename Left, typename Right >
struct concat_vectors;
template< typename ... Left, typename ... Right >
struct concat_vectors< vector< Left... >, vector< Right... > >
{
using type= vector< Left..., Right... >;
};
template< typename Left, typename Right >
using concat_vectors_t= typename concat_vectors< Left, Right >::type;
template< typename Type, typename Group >
struct remove_type_impl;
template< typename Type, typename ... Types >
struct remove_type_impl< Type, vector< Type, Types... > >
{
using type= vector< Types... >;
};
template< typename Type, typename First, typename ... Types >
struct remove_type_impl< Type, vector< First, Types... > >
{
using type= concat_vectors_t< vector< First >, typename remove_type_impl< Type, vector< Types... > >::type >;
};
template< typename Type, typename Vector >
using remove_type_t= typename remove_type_impl< Type, Vector >::type;
template< typename Type >
struct type_sort_vector;
template< typename Type >
struct type_sort_vector< vector< Type > >
{
using type= vector< Type >;
};
template< typename ... Types >
struct type_sort_vector< vector< Types... > >
{
using lowest= lowest_type_t< Types... >;
using type= concat_vectors_t< vector< lowest >, remove_type_t< lowest, vector< Types... > > >;
};
namespace exports
{
template< typename ... Types >
using type_sort_t= typename type_sort_vector< vector< Types... > >::type;
using detail::type_algorithm::type_less_v;
using detail::type_algorithm::single_type_value;
using detail::type_algorithm::char_string_less;
}
}
namespace exports::type_algorithm
{
using namespace detail::type_algorithm::exports;
}
}