C++ initialization of array of tuple's without boilerplate
$begingroup$
Regarding an application written in C++ using the Windows API. I'd like to store a user setting like the window position on program exit, to the Windows registry and retrieve settings like these on the next start of the program.
I currently have 3 settings to be stored/retrieved to/from the registry.
typedef struct tagWINPOS
{
DWORD dwWindowStyle;
int iWindowX;
int iWindowY;
} winpos_t;
HKEY hKeyApp = (HKEY)INVALID_HANDLE_VALUE;
const char szWindowStyle = "WindowStyle";
const char szWindowX = "WindowX";
const char szWindowY = "WindowY";
Later on in the code I'm calling functions like RegSetValueEx and RegQueryValueEx always three times. Like so:
int SaveSettings( HWND hWnd )
{
winpos_t wpos;
// window dimensions from hWnd are stored to wpos, not shown
RegSetValueEx( hKeyApp, szWindowStyle, 0,
REG_DWORD,
(const BYTE*)&wpos.dwWindowStyle,
sizeof(wpos.dwWindowStyle) );
RegSetValueEx( hKeyApp, szWindowX, 0,
REG_DWORD,
(const BYTE*)&wpos.iWindowX,
sizeof(wpos.iWindowX) );
RegSetValueEx( hKeyApp, szWindowY, 0,
REG_DWORD,
(const BYTE*)&wpos.iWindowY,
sizeof(wpos.iWindowY) );
// further irrelevant code removed
}
Things start to look a bit tedious. So I was thinking to put all the parameters for one function call (say RegSetValueEx) into an std::array and then make a for loop iterating over all the array elements.
Because the Windows registry can store multiple data types, like DWORD (32-bit), QWORD (64-bit) and strings. I thought about std::variant to list all of these for this data field.
I'm started with a little test program like this:
#include <cstddef>
#include <cstdio>
#include <cstdint>
#include <tuple>
#include <variant>
typedef std::variant< int32_t, int64_t, char* > data_t;
typedef std::tuple<
data_t, // setting data
const char*, // setting name
std::size_t // size of setting [bytes]
> setting_t;
typedef std::array< setting_t, 2 > settings_t;
constexpr int reg_dword = 0;
constexpr int reg_qword = 1;
constexpr settings_t settings{
std::make_tuple( (std::in_place_index<reg_dword>, 33), "Mydata", 4 ),
std::make_tuple( (std::in_place_index<reg_qword>, 34), "Mydata2", sizeof(std::in_place_index_t<reg_qword>) ) };
int main()
{
printf( "name: %s, value %ldn", std::get<1>( settings[0] ), std::get<0>( std::get<0>( settings[0] ) ));
getchar();
return EXIT_SUCCESS;
}
Anyway, do people consider this approach a good one to get to my goal of having to spell out a single function call of RegSetValueEx inside a for loop?
The initialization of the array has much boilerplate as well as the effort to obtain values. What is a good approach to improve the readability of this? Maybe a constexpr function like std::make_tuple but then more specific for my case?
c++ array c++17
New contributor
$endgroup$
add a comment |
$begingroup$
Regarding an application written in C++ using the Windows API. I'd like to store a user setting like the window position on program exit, to the Windows registry and retrieve settings like these on the next start of the program.
I currently have 3 settings to be stored/retrieved to/from the registry.
typedef struct tagWINPOS
{
DWORD dwWindowStyle;
int iWindowX;
int iWindowY;
} winpos_t;
HKEY hKeyApp = (HKEY)INVALID_HANDLE_VALUE;
const char szWindowStyle = "WindowStyle";
const char szWindowX = "WindowX";
const char szWindowY = "WindowY";
Later on in the code I'm calling functions like RegSetValueEx and RegQueryValueEx always three times. Like so:
int SaveSettings( HWND hWnd )
{
winpos_t wpos;
// window dimensions from hWnd are stored to wpos, not shown
RegSetValueEx( hKeyApp, szWindowStyle, 0,
REG_DWORD,
(const BYTE*)&wpos.dwWindowStyle,
sizeof(wpos.dwWindowStyle) );
RegSetValueEx( hKeyApp, szWindowX, 0,
REG_DWORD,
(const BYTE*)&wpos.iWindowX,
sizeof(wpos.iWindowX) );
RegSetValueEx( hKeyApp, szWindowY, 0,
REG_DWORD,
(const BYTE*)&wpos.iWindowY,
sizeof(wpos.iWindowY) );
// further irrelevant code removed
}
Things start to look a bit tedious. So I was thinking to put all the parameters for one function call (say RegSetValueEx) into an std::array and then make a for loop iterating over all the array elements.
Because the Windows registry can store multiple data types, like DWORD (32-bit), QWORD (64-bit) and strings. I thought about std::variant to list all of these for this data field.
I'm started with a little test program like this:
#include <cstddef>
#include <cstdio>
#include <cstdint>
#include <tuple>
#include <variant>
typedef std::variant< int32_t, int64_t, char* > data_t;
typedef std::tuple<
data_t, // setting data
const char*, // setting name
std::size_t // size of setting [bytes]
> setting_t;
typedef std::array< setting_t, 2 > settings_t;
constexpr int reg_dword = 0;
constexpr int reg_qword = 1;
constexpr settings_t settings{
std::make_tuple( (std::in_place_index<reg_dword>, 33), "Mydata", 4 ),
std::make_tuple( (std::in_place_index<reg_qword>, 34), "Mydata2", sizeof(std::in_place_index_t<reg_qword>) ) };
int main()
{
printf( "name: %s, value %ldn", std::get<1>( settings[0] ), std::get<0>( std::get<0>( settings[0] ) ));
getchar();
return EXIT_SUCCESS;
}
Anyway, do people consider this approach a good one to get to my goal of having to spell out a single function call of RegSetValueEx inside a for loop?
The initialization of the array has much boilerplate as well as the effort to obtain values. What is a good approach to improve the readability of this? Maybe a constexpr function like std::make_tuple but then more specific for my case?
c++ array c++17
New contributor
$endgroup$
add a comment |
$begingroup$
Regarding an application written in C++ using the Windows API. I'd like to store a user setting like the window position on program exit, to the Windows registry and retrieve settings like these on the next start of the program.
I currently have 3 settings to be stored/retrieved to/from the registry.
typedef struct tagWINPOS
{
DWORD dwWindowStyle;
int iWindowX;
int iWindowY;
} winpos_t;
HKEY hKeyApp = (HKEY)INVALID_HANDLE_VALUE;
const char szWindowStyle = "WindowStyle";
const char szWindowX = "WindowX";
const char szWindowY = "WindowY";
Later on in the code I'm calling functions like RegSetValueEx and RegQueryValueEx always three times. Like so:
int SaveSettings( HWND hWnd )
{
winpos_t wpos;
// window dimensions from hWnd are stored to wpos, not shown
RegSetValueEx( hKeyApp, szWindowStyle, 0,
REG_DWORD,
(const BYTE*)&wpos.dwWindowStyle,
sizeof(wpos.dwWindowStyle) );
RegSetValueEx( hKeyApp, szWindowX, 0,
REG_DWORD,
(const BYTE*)&wpos.iWindowX,
sizeof(wpos.iWindowX) );
RegSetValueEx( hKeyApp, szWindowY, 0,
REG_DWORD,
(const BYTE*)&wpos.iWindowY,
sizeof(wpos.iWindowY) );
// further irrelevant code removed
}
Things start to look a bit tedious. So I was thinking to put all the parameters for one function call (say RegSetValueEx) into an std::array and then make a for loop iterating over all the array elements.
Because the Windows registry can store multiple data types, like DWORD (32-bit), QWORD (64-bit) and strings. I thought about std::variant to list all of these for this data field.
I'm started with a little test program like this:
#include <cstddef>
#include <cstdio>
#include <cstdint>
#include <tuple>
#include <variant>
typedef std::variant< int32_t, int64_t, char* > data_t;
typedef std::tuple<
data_t, // setting data
const char*, // setting name
std::size_t // size of setting [bytes]
> setting_t;
typedef std::array< setting_t, 2 > settings_t;
constexpr int reg_dword = 0;
constexpr int reg_qword = 1;
constexpr settings_t settings{
std::make_tuple( (std::in_place_index<reg_dword>, 33), "Mydata", 4 ),
std::make_tuple( (std::in_place_index<reg_qword>, 34), "Mydata2", sizeof(std::in_place_index_t<reg_qword>) ) };
int main()
{
printf( "name: %s, value %ldn", std::get<1>( settings[0] ), std::get<0>( std::get<0>( settings[0] ) ));
getchar();
return EXIT_SUCCESS;
}
Anyway, do people consider this approach a good one to get to my goal of having to spell out a single function call of RegSetValueEx inside a for loop?
The initialization of the array has much boilerplate as well as the effort to obtain values. What is a good approach to improve the readability of this? Maybe a constexpr function like std::make_tuple but then more specific for my case?
c++ array c++17
New contributor
$endgroup$
Regarding an application written in C++ using the Windows API. I'd like to store a user setting like the window position on program exit, to the Windows registry and retrieve settings like these on the next start of the program.
I currently have 3 settings to be stored/retrieved to/from the registry.
typedef struct tagWINPOS
{
DWORD dwWindowStyle;
int iWindowX;
int iWindowY;
} winpos_t;
HKEY hKeyApp = (HKEY)INVALID_HANDLE_VALUE;
const char szWindowStyle = "WindowStyle";
const char szWindowX = "WindowX";
const char szWindowY = "WindowY";
Later on in the code I'm calling functions like RegSetValueEx and RegQueryValueEx always three times. Like so:
int SaveSettings( HWND hWnd )
{
winpos_t wpos;
// window dimensions from hWnd are stored to wpos, not shown
RegSetValueEx( hKeyApp, szWindowStyle, 0,
REG_DWORD,
(const BYTE*)&wpos.dwWindowStyle,
sizeof(wpos.dwWindowStyle) );
RegSetValueEx( hKeyApp, szWindowX, 0,
REG_DWORD,
(const BYTE*)&wpos.iWindowX,
sizeof(wpos.iWindowX) );
RegSetValueEx( hKeyApp, szWindowY, 0,
REG_DWORD,
(const BYTE*)&wpos.iWindowY,
sizeof(wpos.iWindowY) );
// further irrelevant code removed
}
Things start to look a bit tedious. So I was thinking to put all the parameters for one function call (say RegSetValueEx) into an std::array and then make a for loop iterating over all the array elements.
Because the Windows registry can store multiple data types, like DWORD (32-bit), QWORD (64-bit) and strings. I thought about std::variant to list all of these for this data field.
I'm started with a little test program like this:
#include <cstddef>
#include <cstdio>
#include <cstdint>
#include <tuple>
#include <variant>
typedef std::variant< int32_t, int64_t, char* > data_t;
typedef std::tuple<
data_t, // setting data
const char*, // setting name
std::size_t // size of setting [bytes]
> setting_t;
typedef std::array< setting_t, 2 > settings_t;
constexpr int reg_dword = 0;
constexpr int reg_qword = 1;
constexpr settings_t settings{
std::make_tuple( (std::in_place_index<reg_dword>, 33), "Mydata", 4 ),
std::make_tuple( (std::in_place_index<reg_qword>, 34), "Mydata2", sizeof(std::in_place_index_t<reg_qword>) ) };
int main()
{
printf( "name: %s, value %ldn", std::get<1>( settings[0] ), std::get<0>( std::get<0>( settings[0] ) ));
getchar();
return EXIT_SUCCESS;
}
Anyway, do people consider this approach a good one to get to my goal of having to spell out a single function call of RegSetValueEx inside a for loop?
The initialization of the array has much boilerplate as well as the effort to obtain values. What is a good approach to improve the readability of this? Maybe a constexpr function like std::make_tuple but then more specific for my case?
c++ array c++17
c++ array c++17
New contributor
New contributor
New contributor
asked 40 mins ago
ZeynebZeyneb
1
1
New contributor
New contributor
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Zeyneb is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212891%2fc-initialization-of-array-of-tuples-without-boilerplate%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Zeyneb is a new contributor. Be nice, and check out our Code of Conduct.
Zeyneb is a new contributor. Be nice, and check out our Code of Conduct.
Zeyneb is a new contributor. Be nice, and check out our Code of Conduct.
Zeyneb is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212891%2fc-initialization-of-array-of-tuples-without-boilerplate%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown