Skip to content

Add C++ modules support#442

Open
mikomikotaishi wants to merge 3 commits intoLASTRADA-Software:masterfrom
mikomikotaishi:master
Open

Add C++ modules support#442
mikomikotaishi wants to merge 3 commits intoLASTRADA-Software:masterfrom
mikomikotaishi:master

Conversation

@mikomikotaishi
Copy link

@mikomikotaishi mikomikotaishi commented Feb 10, 2026

This PR adds support for C++ modules.

Using statements are sorted in alphabetical order so that it is easier to maintain.

@mikomikotaishi mikomikotaishi requested a review from a team as a code owner February 10, 2026 00:10
@github-actions github-actions bot added documentation Improvements or additions to documentation Query Builder Data Binder SQL Data Binder support CMake labels Feb 10, 2026
@Yaraslaut
Copy link
Member

Hi, thanks for the PR, I think we need to consume somewhere Lightweight module to ensure that everything works, for instance chinook example is a good place: https://github.com/LASTRADA-Software/Lightweight/tree/master/src/examples/test_chinook

@mikomikotaishi
Copy link
Author

Sure, I can add a test for the modules.

@mikomikotaishi
Copy link
Author

I have a test now for the modules

@mikomikotaishi
Copy link
Author

@Yaraslaut @christianparpart could you review the tests?

@Yaraslaut
Copy link
Member

I think we should avoid duplication of the source code, the easiest would be to update existing chinook example with the module usage, since we also check this example in the CI, no need for duplication, because then we need make sure that everything is syncronized

@mikomikotaishi
Copy link
Author

@Yaraslaut The code is now unified, with macro guards to decide between module imports and includes.

Copy link
Member

@Yaraslaut Yaraslaut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the update, nothing big, the only point that i am worried about is qualified names, such that name resolution is as simple as possible


#include "Artist.hpp"

#include <Lightweight/DataMapper/DataMapper.hpp>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to import Lightweight; here instead? since this should be enough to include this header to start using the struct, and order of the includes should not matter

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do it with the headers, because I made sure the standard library would be included beforehand.

I guess you're suggesting something like

#ifdef LIGHTWEIGHT_BUILD_MODULES
import Lightweight;
#else
#include <Lightweight/DataMapper/DataMapper.hpp>
#endif

but this is a bad idea. import statements MUST appear all at the top of a file, and if we were to do this, we would get something like

#include "entities/Album.hpp"
#include "entities/Artist.hpp"

could expand into

import Lightweight;

struct Album final { /* ... */ };

import Lightweight;

struct Artist final { /* ... */ };

and an import statement would be coming after code, which is rejected by the compiler.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting, you can notice that one of the ci checks is failing that checks ddl2cpp. This is a small tool that generates this header files for the database, see: https://github.com/LASTRADA-Software/Lightweight/actions/runs/22004219452/job/63585918320

So I guess we need to find a way to deal with this hear

Comment on lines 17 to 33
using std::basic_string_view;
using std::format_string;
using std::optional;
using std::string;
using std::string_view;

using Lightweight::BelongsTo;
using Lightweight::DataMapper;
using Lightweight::Field;
using Lightweight::PrimaryKey;
using Lightweight::SqlConnection;
using Lightweight::SqlConnectionString;
using Lightweight::SqlDateTime;
using Lightweight::SqlDynamicUtf16String;
using Lightweight::SqlNullable;
using Lightweight::SqlNumeric;
using Lightweight::SqlRealName;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think that this is a good idea to drop all qualifiers, such as namespaces

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example previously already used using namespace Lightweight; I'm doing this because if we had done that already, then there isn't much of a reason not to do this, but instead of using namespace individual using statements are probably better to make it clear what types originate from what.

But, on the topic of qualification, I think in these examples it's usually clear from context what the symbols refer to. using gives us readability, while not losing context of what library symbols originate from where.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, did not notice, indeed the case, we can keep it like this, this is ok

Comment on lines +12 to +20
Field<int32_t, PrimaryKey::ServerSideAutoIncrement, SqlRealName { "TrackId" }> TrackId;
Field<SqlDynamicUtf16String<200>, SqlRealName { "Name" }> Name;
BelongsTo<&Album::AlbumId, SqlRealName { "AlbumId" }, SqlNullable::Null> AlbumId;
BelongsTo<&Mediatype::MediaTypeId, SqlRealName { "MediaTypeId" }> MediaTypeId;
BelongsTo<&Genre::GenreId, SqlRealName { "GenreId" }, SqlNullable::Null> GenreId;
Field<optional<SqlDynamicUtf16String<220>>, SqlRealName { "Composer" }> Composer;
Field<int32_t, SqlRealName { "Milliseconds" }> Milliseconds;
Field<optional<int32_t>, SqlRealName { "Bytes" }> Bytes;
Field<SqlNumeric<10, 2>, SqlRealName { "UnitPrice" }> UnitPrice;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am slightly confused
why qualifiers removed here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the qualifiers because I ensured they were added into scope before the #include directives were used. (As for why I de-qualified, I think it's easier to read and maintain, not to mention the original example already used using namespace Lightweight; previously.

@mikomikotaishi
Copy link
Author

Is it a problem in this example? The symbols all belong to either the library or std, so I decided to import names into scope to make code easier to read

Copy link
Member

@Yaraslaut Yaraslaut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that everything is ok, just need to fix compilation and do something about ddl2cpp.
I guess what we want to do, is to add some kind of guard in this headers for the module support, and introduce this guard in the ddl2cpp as well

Comment on lines 17 to 33
using std::basic_string_view;
using std::format_string;
using std::optional;
using std::string;
using std::string_view;

using Lightweight::BelongsTo;
using Lightweight::DataMapper;
using Lightweight::Field;
using Lightweight::PrimaryKey;
using Lightweight::SqlConnection;
using Lightweight::SqlConnectionString;
using Lightweight::SqlDateTime;
using Lightweight::SqlDynamicUtf16String;
using Lightweight::SqlNullable;
using Lightweight::SqlNumeric;
using Lightweight::SqlRealName;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, did not notice, indeed the case, we can keep it like this, this is ok


#include "Artist.hpp"

#include <Lightweight/DataMapper/DataMapper.hpp>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting, you can notice that one of the ci checks is failing that checks ddl2cpp. This is a small tool that generates this header files for the database, see: https://github.com/LASTRADA-Software/Lightweight/actions/runs/22004219452/job/63585918320

So I guess we need to find a way to deal with this hear

@mikomikotaishi
Copy link
Author

OK, let's see if this fixes the ddl2cpp CI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CMake Data Binder SQL Data Binder support documentation Improvements or additions to documentation Query Builder

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants