Remove concepts dependency, switch temporally Linux nightly to clang.

This commit is contained in:
Martín Lucas Golini
2026-05-03 19:40:56 -03:00
parent 03a798820d
commit da30372aae
7 changed files with 52 additions and 64 deletions

View File

@@ -52,14 +52,14 @@ jobs:
container:
image: ubuntu:20.04
env:
CC: gcc
CXX: g++
CC: clang-20
CXX: clang++-20
steps:
- name: Install essentials
run: |
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends software-properties-common build-essential git ca-certificates
apt-get install -y --no-install-recommends software-properties-common build-essential git ca-certificates wget lsb-release gnupg
- name: Checkout Code
uses: actions/checkout@v6
with: { fetch-depth: 0, submodules: 'recursive', set-safe-directory: true }
@@ -77,44 +77,30 @@ jobs:
- name: Install dependencies
shell: bash
run: |
apt-get install -y curl libfuse2 fuse premake4 mesa-common-dev libgl1-mesa-dev sudo file appstream
apt-get install -y curl libfuse2 fuse premake4 mesa-common-dev libgl1-mesa-dev sudo file appstream libdw-dev
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
apt-get install -y nodejs
add-apt-repository -y universe
add-apt-repository -y multiverse
SUCCESS=false
for i in {1..3}; do
echo "Attempt $i: Adding PPA via Launchpad API..."
if timeout 30s sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; then
SUCCESS=true
echo "Successfully added PPA."
break
fi
echo "Launchpad API failed or timed out. Retrying in 5 seconds..."
sleep 5
done
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
./llvm.sh 20
if [ "$SUCCESS" = false ]; then
echo "add-apt-repository failed 3 times. Executing manual fallback..."
. /etc/os-release
echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu $VERSION_CODENAME main" | sudo tee /etc/apt/sources.list.d/ubuntu-toolchain-r-fallback.list
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 60C317803A41BA51845E371A1E9377A2BA9EF27F || true
fi
apt-get install -y libc++-20-dev libc++abi-20-dev
update-alternatives --install /usr/bin/cc cc /usr/bin/clang-20 30
update-alternatives --set cc /usr/bin/clang-20
update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-20 30
update-alternatives --set c++ /usr/bin/clang++-20
sudo apt-get update
apt-get install -y gcc-13 g++-13 libdw-dev
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 10
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 10
update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
update-alternatives --set cc /usr/bin/gcc
update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
update-alternatives --set c++ /usr/bin/g++
update-alternatives --config gcc
update-alternatives --config g++
bash projects/linux/scripts/install_sdl2.sh
- name: Build ecode
run: |
export CC="clang-20"
export CXX="clang++-20 -stdlib=libc++"
export LDFLAGS="-stdlib=libc++"
bash projects/linux/ecode/build.app.sh --with-static-cpp --version ${{ env.INSTALL_REF }} --arch ${{ matrix.config.arch }}
- name: Upload Files
uses: softprops/action-gh-release@v3

View File

@@ -406,7 +406,7 @@ class EE_API Color : public tColor<Uint8> {
static void initColorMap();
template <AllowedFunctionString StringType>
template <typename StringType>
static bool isColorStringT( StringType str, bool searchColorNames );
};

View File

@@ -5,13 +5,8 @@
#include <eepp/core/small_vector.hpp>
#include <eepp/core/string.hpp>
#include <concepts>
#include <string>
template <typename T>
concept AllowedFunctionString =
std::same_as<T, std::string_view> || std::same_as<T, EE::String::View>;
namespace EE { namespace System {
class EE_API FunctionString {
@@ -19,10 +14,14 @@ class EE_API FunctionString {
using Parameters = SmallVector<std::string, 4>;
using TypeStringVector = SmallVector<bool, 4>;
static FunctionString parse( const std::string& function );
static FunctionString parse( std::string_view function );
static FunctionString parse( String::View function );
FunctionString() {}
FunctionString( const std::string& name, const Parameters& parameters,
const TypeStringVector& typeStringData );
@@ -42,7 +41,7 @@ class EE_API FunctionString {
Parameters parameters;
TypeStringVector typeStringData;
template <AllowedFunctionString StringType> static FunctionString parse( StringType function );
template <typename StringType> static FunctionString parse( StringType function );
};
}} // namespace EE::System

View File

@@ -22,7 +22,7 @@ typedef std::function<bool( const UIWidget* node, int a, int b, const FunctionSt
struct StructuralSelector {
StructuralSelector( StyleSheetNodeSelector selector, int a = 0, int b = 0,
const FunctionString& data = FunctionString::parse( "" ) ) :
const FunctionString& data = {} ) :
selector( selector ), a( a ), b( b ), data( data ) {}
StyleSheetNodeSelector selector;
int a;

View File

@@ -715,7 +715,7 @@ Color Color::fromString( std::string str ) {
return Color::Transparent;
}
template <AllowedFunctionString StringType>
template <typename StringType>
bool Color::isColorStringT( StringType str, bool searchColorNames ) {
if ( str.empty() )
return false;

View File

@@ -2,13 +2,12 @@
#include <eepp/core/string.hpp>
#include <eepp/system/functionstring.hpp>
#include <concepts>
#include <string>
#include <type_traits>
namespace EE { namespace System {
template <AllowedFunctionString StringType>
FunctionString FunctionString::parse( StringType function ) {
template <typename StringType> FunctionString FunctionString::parse( StringType function ) {
using CharType = typename StringType::value_type;
size_t funcSep = function.find( '(' );
@@ -35,7 +34,7 @@ FunctionString FunctionString::parse( StringType function ) {
int parenDepth = 0;
auto pushBufferToParams = [&]() {
if constexpr ( std::same_as<CharType, char> ) {
if constexpr ( std::is_same_v<CharType, char> ) {
if ( !currentParamIsString )
String::trimInPlace( buffer );
funcParameters.push_back( buffer );
@@ -109,13 +108,17 @@ FunctionString FunctionString::parse( StringType function ) {
if ( !buffer.empty() || currentParamIsString )
pushBufferToParams();
if constexpr ( std::same_as<StringType, std::string> ) {
if constexpr ( std::is_same_v<StringType, std::string> ) {
return FunctionString( std::string{ funcName }, funcParameters, typeStringData );
} else {
return FunctionString( String( funcName ).toUtf8(), funcParameters, typeStringData );
}
}
FunctionString FunctionString::parse( const std::string& function ) {
return parse<std::string_view>( std::string_view{ function } );
}
FunctionString FunctionString::parse( std::string_view function ) {
return parse<std::string_view>( function );
}

View File

@@ -189,9 +189,9 @@ UTEST( UITextNode_CSSSelectors, EmptyWithTextNodes ) {
ASSERT_TRUE( rtEmpty != nullptr );
// rtText has a text node child → NOT empty
EXPECT_FALSE( emptySel.selector( rtText, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_FALSE( emptySel.selector( rtText, 0, 0, FunctionString() ) );
// rtEmpty has no children → empty
EXPECT_TRUE( emptySel.selector( rtEmpty, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( emptySel.selector( rtEmpty, 0, 0, FunctionString() ) );
destroyRichTextScene( sceneNode );
}
@@ -220,8 +220,8 @@ UTEST( UITextNode_CSSSelectors, FirstChildWithTextNodes ) {
ASSERT_TRUE( elem0 != nullptr );
ASSERT_TRUE( elem1 != nullptr );
EXPECT_TRUE( sel.selector( elem0, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_FALSE( sel.selector( elem1, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( elem0, 0, 0, FunctionString() ) );
EXPECT_FALSE( sel.selector( elem1, 0, 0, FunctionString() ) );
destroyRichTextScene( sceneNode );
}
@@ -250,8 +250,8 @@ UTEST( UITextNode_CSSSelectors, LastChildWithTextNodes ) {
ASSERT_TRUE( elem0 != nullptr );
ASSERT_TRUE( elem1 != nullptr );
EXPECT_FALSE( sel.selector( elem0, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( elem1, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_FALSE( sel.selector( elem0, 0, 0, FunctionString() ) );
EXPECT_TRUE( sel.selector( elem1, 0, 0, FunctionString() ) );
destroyRichTextScene( sceneNode );
}
@@ -279,7 +279,7 @@ UTEST( UITextNode_CSSSelectors, OnlyChildWithTextNodes ) {
ASSERT_TRUE( elem0 != nullptr );
// Text nodes are invisible → elem0 IS the only element child
EXPECT_TRUE( sel.selector( elem0, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( elem0, 0, 0, FunctionString() ) );
destroyRichTextScene( sceneNode );
}
@@ -311,9 +311,9 @@ UTEST( UITextNode_CSSSelectors, FirstOfTypeWithTextNodes ) {
Node* br0 = sceneNode->find( "br0" );
ASSERT_TRUE( br0 != nullptr );
EXPECT_TRUE( sel.selector( span0, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_FALSE( sel.selector( span1, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( static_cast<UIWidget*>( br0 ), 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( span0, 0, 0, FunctionString() ) );
EXPECT_FALSE( sel.selector( span1, 0, 0, FunctionString() ) );
EXPECT_TRUE( sel.selector( static_cast<UIWidget*>( br0 ), 0, 0, FunctionString() ) );
destroyRichTextScene( sceneNode );
}
@@ -411,8 +411,8 @@ UTEST( UITextNode_CSSSelectors, OnlyOfTypeWithTextNodes ) {
ASSERT_TRUE( br0 != nullptr );
// Each is the only one of its C++ type
EXPECT_TRUE( sel.selector( span0, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( static_cast<UIWidget*>( br0 ), 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( span0, 0, 0, FunctionString() ) );
EXPECT_TRUE( sel.selector( static_cast<UIWidget*>( br0 ), 0, 0, FunctionString() ) );
destroyRichTextScene( sceneNode );
}
@@ -443,9 +443,9 @@ UTEST( UITextNode_CSSSelectors, LastOfTypeWithTextNodes ) {
Node* br0 = sceneNode->find( "br0" );
ASSERT_TRUE( br0 != nullptr );
EXPECT_FALSE( sel.selector( span0, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( span1, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( static_cast<UIWidget*>( br0 ), 0, 0, FunctionString::parse( "" ) ) );
EXPECT_FALSE( sel.selector( span0, 0, 0, FunctionString() ) );
EXPECT_TRUE( sel.selector( span1, 0, 0, FunctionString() ) );
EXPECT_TRUE( sel.selector( static_cast<UIWidget*>( br0 ), 0, 0, FunctionString() ) );
destroyRichTextScene( sceneNode );
}
@@ -1048,7 +1048,7 @@ UTEST( UITextNode_Regression, ElementCountingDoesNotCountDeletedNodes ) {
ASSERT_TRUE( elem0 != nullptr );
// elem0 is first element child (text node skipped)
EXPECT_TRUE( sel.selector( elem0, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( elem0, 0, 0, FunctionString() ) );
destroyRichTextScene( sceneNode );
}
@@ -1078,14 +1078,14 @@ UTEST( UITextNode_Regression, OnlyOfTypeStaysCorrectAfterModification ) {
ASSERT_TRUE( br0 != nullptr );
// Each is only-of-type
EXPECT_TRUE( sel.selector( span0, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( static_cast<UIWidget*>( br0 ), 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( span0, 0, 0, FunctionString() ) );
EXPECT_TRUE( sel.selector( static_cast<UIWidget*>( br0 ), 0, 0, FunctionString() ) );
// Remove br0 → span0 still only-of-type
br0->detach();
eeDelete( br0 );
EXPECT_TRUE( sel.selector( span0, 0, 0, FunctionString::parse( "" ) ) );
EXPECT_TRUE( sel.selector( span0, 0, 0, FunctionString() ) );
destroyRichTextScene( sceneNode );
}