1
0
forked from Alepha/Alepha

Rename the template_for header.

C++26 (I hope) is supposed to have this syntax:

```
template for( const auto &element: aggregate )
{
	...;
}
```

Thus, I've adjusted this gadget to have a similar name, to enable
simple mechanical code changes.  From Alepha, you'd use it
thus:

```
template_for( aggregate ) <=[&]( const auto &element )
{
	...;
};
```
This commit is contained in:
2024-07-05 11:59:26 -04:00
parent b5fb8c76f2
commit 32e6c36570
7 changed files with 5 additions and 5 deletions

115
template_for.h Normal file
View File

@ -0,0 +1,115 @@
static_assert( __cplusplus > 2020'99 );
#pragma once
#include <Alepha/Alepha.h>
#include <type_traits>
#include <Alepha/Concepts.h>
#include <Alepha/Reflection/tuplizeAggregate.h>
namespace Alepha::Hydrogen ::detail:: template_for_each_m
{
inline namespace exports
{
constexpr void tuple_for_each( const std::tuple<> &, const Functional auto ) noexcept {}
template< typename ... Args, typename Function >
constexpr void
tuple_for_each( const std::tuple< Args... > &tuple, Function body )
noexcept
(
( ... and noexcept( body( std::declval< const Args & >() ) ) )
)
{
const auto callWrapper= [&body]( auto &&element ) { body( element ); return nullptr; };
auto loop_body_handler= [&]( auto &&... tuple_elements )
{
std::nullptr_t expansion[]= { callWrapper( tuple_elements )... };
std::ignore= expansion;
};
std::apply( loop_body_handler, tuple );
}
// Apply type_identity to all tuple elements
template< typename > struct type_identify_tuple;
template< typename T >
using type_identify_tuple_t= typename type_identify_tuple< T >::type;
template<> struct type_identify_tuple< std::tuple<> > { using type= std::tuple<>; };
template< typename ... Args >
struct type_identify_tuple< std::tuple< Args... > >
{
using type= std::tuple< std::type_identity< Args >... >;
};
// Nicer for-each syntax helper:
template< typename Tuple >
struct for_each_syntax_adaptor
{
Tuple &tuple;
template< typename Function >
constexpr void
operator <= ( Function &&func ) noexcept( noexcept( tuple_for_each( tuple, std::forward< Function >( func ) ) ) )
{
return tuple_for_each( tuple, std::forward< Function >( func ) );
}
constexpr operator decltype( std::ignore ) () const= delete;
};
template< typename Tuple >
[[nodiscard]]
constexpr auto
tuple_for_each( Tuple &tuple ) noexcept
{
return for_each_syntax_adaptor< Tuple >{ tuple };
}
template< typename Tuple >
[[nodiscard]]
constexpr auto
tuple_for_each( const Tuple &tuple ) noexcept
{
return for_each_syntax_adaptor< const Tuple >{ tuple };
}
template< typename Type >
concept TemplateLoopable= false
or Tuple< Type >
or Aggregate< Type >
// or Array< T > // Do we need array support? Does it matter?
;
template< TemplateLoopable Type >
[[nodiscard]]
constexpr auto
template_for( Type &tuple, std::optional< Reflection::aggregate_tuple_t< Type > > &&tupled= {} ) noexcept
{
tupled= Reflection::tuplizeAggregate( tuple );
return tuple_for_each( *tupled );
}
template< TemplateLoopable Type >
[[nodiscard]]
constexpr auto
template_for( const Type &tuple, std::optional< Reflection::aggregate_tuple_t< Type > > &&tupled= {} ) noexcept
{
tupled= Reflection::tuplizeAggregate( tuple );
return tuple_for_each( *tupled );
}
}
}
namespace Alepha::Hydrogen::inline exports::inline template_for_each_m
{
using namespace detail::template_for_each_m::exports;
}