Date: Fri, 19 Jul 2024 10:59:23 +0100
On Thu, Jul 18, 2024 at 11:58 PM Tiago Freire wrote:
>
> I have just seen you change the design 3 times with
> the drop of a hat every time some one mentions a
> new type of code flow. And there's no guarantee that
> tomorrow you won't change it again once you remember
> something else.
I'm blushing Tiago, you flatter me. I have been known to quickly
improvise and come out with innovative designs at the drop of a hat,
thank you. My favourite flower is still the tulip and I'm unwilling to
compromise on beauty -- perhaps it really is in the eye of the
beholder but I adamantly assert that there is innate beauty in the
tulip.
Let's do another complex NRVO function. Let's say we have a function
with the following signature:
std::fstream GetLicenseFile(void);
This function will go through all the files in the current directory,
opening them one by one and looking for one that starts with the
3-byte sequence "LIS", and returning the 'fstream' for that file. If
no such file can be found, a new file is created called
"new_license_file.txt".
The "std::fstream" class is actually movable but let's pretend it's
both unmovable-and-uncopyable. If we had NRVO in C++, it would look
something like:
std::fstream GetLicenseFile(void)
{
typedef std::filesystem::directory_iterator DirIt;
DirIt it{ std::filesystem::current_path() };
for ( DirIt it(std::filesystem::current_path()); DirIt() != it; ++it )
{
std::fstream a( it->path().string() );
if ( a.is_open() )
{
char buf[3u] = {};
a.read(buf,3u);
if ( 3u==a.gcount() && 'L'==buf[0] && 'I'==buf[1] &&
'S'==buf[2] ) return a;
}
}
return std::fstream("new_license_file.txt");
}
With P3357, this function would be written as:
std::fstream GetLicenseFile(void)
{
using std::fstream;
constexpr auto something_went_wrong =
+[](void) -> fstream
{
return fstream("new_license_file.txt");
};
typedef std::filesystem::directory_iterator DirIt;
DirIt it{ std::filesystem::current_path() };
if ( DirIt() == it ) return something_went_wrong();
std::string name = it->path().string();
return std::construct_modify_retry<fstream>(
name, // passed by reference
[&](auto &a) -> Status
{
if ( a.is_open() )
{
char buf[3u] = {};
a.read(buf,3u);
if ( 3u==a.gcount() && 'L'==buf[0] && 'I'==buf[1]
&& 'S'==buf[2] ) return Success;
}
if ( DirIt() == ++it ) return Fail;
name = it->path().string();
return Retry;
},
something_went_wrong
);
}
which is tested and working on this GodBolt:
https://msvc.godbolt.org/z/6jdWaMWjo
>
> I have just seen you change the design 3 times with
> the drop of a hat every time some one mentions a
> new type of code flow. And there's no guarantee that
> tomorrow you won't change it again once you remember
> something else.
I'm blushing Tiago, you flatter me. I have been known to quickly
improvise and come out with innovative designs at the drop of a hat,
thank you. My favourite flower is still the tulip and I'm unwilling to
compromise on beauty -- perhaps it really is in the eye of the
beholder but I adamantly assert that there is innate beauty in the
tulip.
Let's do another complex NRVO function. Let's say we have a function
with the following signature:
std::fstream GetLicenseFile(void);
This function will go through all the files in the current directory,
opening them one by one and looking for one that starts with the
3-byte sequence "LIS", and returning the 'fstream' for that file. If
no such file can be found, a new file is created called
"new_license_file.txt".
The "std::fstream" class is actually movable but let's pretend it's
both unmovable-and-uncopyable. If we had NRVO in C++, it would look
something like:
std::fstream GetLicenseFile(void)
{
typedef std::filesystem::directory_iterator DirIt;
DirIt it{ std::filesystem::current_path() };
for ( DirIt it(std::filesystem::current_path()); DirIt() != it; ++it )
{
std::fstream a( it->path().string() );
if ( a.is_open() )
{
char buf[3u] = {};
a.read(buf,3u);
if ( 3u==a.gcount() && 'L'==buf[0] && 'I'==buf[1] &&
'S'==buf[2] ) return a;
}
}
return std::fstream("new_license_file.txt");
}
With P3357, this function would be written as:
std::fstream GetLicenseFile(void)
{
using std::fstream;
constexpr auto something_went_wrong =
+[](void) -> fstream
{
return fstream("new_license_file.txt");
};
typedef std::filesystem::directory_iterator DirIt;
DirIt it{ std::filesystem::current_path() };
if ( DirIt() == it ) return something_went_wrong();
std::string name = it->path().string();
return std::construct_modify_retry<fstream>(
name, // passed by reference
[&](auto &a) -> Status
{
if ( a.is_open() )
{
char buf[3u] = {};
a.read(buf,3u);
if ( 3u==a.gcount() && 'L'==buf[0] && 'I'==buf[1]
&& 'S'==buf[2] ) return Success;
}
if ( DirIt() == ++it ) return Fail;
name = it->path().string();
return Retry;
},
something_went_wrong
);
}
which is tested and working on this GodBolt:
https://msvc.godbolt.org/z/6jdWaMWjo
Received on 2024-07-19 09:59:36