#Tomllib dosent work as expected

150 messages · Page 1 of 1 (latest)

north knot
#

Im having trouble parsing through all the entries in the default map where parsing through all the values in the default_config map
and assigning the map value to the name that tomllib finds dosent work

  const ConfigValue::config_map default_config = {
    {"Log-path", this->log_path},
    {"Username", this->username},
    {"User-ID", this->user_id},
    {"User-profile", this->user_profile},
    {"Message", this->message},
    {"Message-Timestamp", this->message_timestamp}
};

THis is the map I want to parse through and assign values with all the key members being in the class aswell

ConfigResult<ConfigValue> ConfigClass::LoggingConfig::load_config()const{
toml::table tbl = toml::parse_file(static_config_path_t);
auto logging = tbl["Logging"];

}
This is the shell of the function

How would I make this for function so that it works?

final robinBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

grizzled dawn
#

I'm not sure what you are trying to do?

#

what have you tried that doesn't work?

#

and in what way does it not work?

north knot
#

ConfigResult<ConfigValue> ConfigClass::LoggingConfig::load_config()const{
toml::table tbl = toml::parse_file(static_config_path_t);
auto logging = tbl["Logging"];
for(auto& [name, value] : default_config){
using value_decl_t = decltype(std::decay_t<value>);
value = logging<value_decl_t>(name);
}
}

Something like this

grizzled dawn
#

decltype is compile time, and for loops don't support changing types, so having it is not useful

north knot
#

Then how would you suggest doing it?

grizzled dawn
#

this looks like you are trying to use some sort of reflection to make different types.

#

c++ does not have this feature, you will have to write it yourself (or use a library)

north knot
#

Libary suggestions?

#

And code with the libary if its not too much to ask

grizzled dawn
#

well I still don't really understand what you are trying to do

#

also fair warning, I usually go write it myself approach so my library choices on this topic are likely bad

north knot
#

So what im trying to do is loop through the map with the type names:

So if you look at this:

  const ConfigValue::config_map default_config = {
    {"Log-path", log_path},
    {"Username", this->username},
    {"User-ID", this->user_id},
    {"User-profile", this->user_profile},
    {"Message", this->message},
    {"Message-Timestamp", message_timestamp}
};



  /**
  * @brief specifies log path
  */
  static file_t log_path;

  /**
  * @brief set if username should be included in log, recommended setting
  */
  static bool username;
    
  /**
  * @brief set if user id should be included in log
  */
  static bool user_id;

  /**
  * @brief set if user profile picture should be included in log
  */
  static bool user_profile;

  /**
  * @brief set if message should be included in log, recommended setting
  */
  static bool message;

  /**
  * @brief set if message timestamp should be included in log
  */
  static bool message_timestamp;

So map is used to refrence them so when you assign a value to the map value it will assign that value to the class variable

grizzled dawn
#

you should use code formatting

final robinBOT
#
How to Format Code on Discord
Markup

```cpp
int main() {}
```

Result
int main() {}
north knot
#

Its going to get fixed later

#

Thats not the issue im worried about

grizzled dawn
#

no I mean

#

so I can read it

grizzled dawn
north knot
#

And you do that with?

grizzled dawn
#

the bot message explains it

final robinBOT
#
How to Format Code on Discord
Markup

```cpp
int main() {}
```

Result
int main() {}
north knot
#

Okay there

#

Yea okay

final robinBOT
#
How to Format Code on Discord
Markup

```cpp
int main() {}
```

Result
int main() {}
grizzled dawn
#

that explains it

final robinBOT
#
How to Format Code on Discord
Markup

```cpp
int main() {}
```

Result
int main() {}
grizzled dawn
#

read the message

north knot
#

So withing these brackets

#

Okay

grizzled dawn
#

```cpp
int main();
```
renders as

int main()
north knot
#

    public:
      /** @note remove static when this is changed */
      
      /**
      * @brief specifies log path
      */
      static file_t log_path;

      /**
      * @brief set if username should be included in log, recommended setting
      */
      static bool username;
        
      /**
      * @brief set if user id should be included in log
      */
      static bool user_id;

      /**
      * @brief set if user profile picture should be included in log
      */
      static bool user_profile;

      /**
      * @brief set if message should be included in log, recommended setting
      */
      static bool message;

      /**
      * @brief set if message timestamp should be included in log
      */
      static bool message_timestamp;


    public:
      /** @note remove static when this is changed */
      
      /**
      * @brief specifies log path
      */
      static file_t log_path;

      /**
      * @brief set if username should be included in log, recommended setting
      */
      static bool username;
        
      /**
      * @brief set if user id should be included in log
      */
      static bool user_id;

      /**
      * @brief set if user profile picture should be included in log
      */
      static bool user_profile;

      /**
      * @brief set if message should be included in log, recommended setting
      */
      static bool message;

      /**
      * @brief set if message timestamp should be included in log
      */
      static bool message_timestamp;


      const ConfigValue::config_map default_config = {
        {"Log-path", log_path},
        {"Username", this->username},
        {"User-ID", this->user_id},
        {"User-profile", this->user_profile},
        {"Message", this->message},
        {"Message-Timestamp", message_timestamp}
    };
grizzled dawn
#

much better thank you

north knot
#

You are welcome

grizzled dawn
#

though you should add the cpp tag to highlight it like C++ but shrug

north knot
#
/** @note trouble fixing code*/
ConfigResult<ConfigValue> ConfigClass::LoggingConfig::load_config()const{
  toml::table tbl = toml::parse_file(static_config_path_t);
  auto logging = tbl["Logging"];
  for(auto& [name, value] : default_config){
    using value_decl_t = decltype(std::decay_t<value>);
    value = logging<value_decl_t>(name);
  }
}
final robinBOT
#

@north knot

It looks like you may have code formatting errors in your message

Note: Make sure to use back-ticks (`) and not quotes (')
Note: Make sure to specify a highlighting language, e.g. `cpp`, after the back-ticks

Markup

```cpp
int main() {}
```

Result
int main() {}
north knot
#

Ahhh yea mb

grizzled dawn
north knot
#

Its another class

#

Return type is not important

grizzled dawn
north knot
#

Nor the function itself

#

Yes

#

No

#

Its not

#

I just named it that

#

I dont know what to name it other then that

#

Its only purpose is pretty much to loop through all the values and assign them to the class variables

#

So the name is not important

#

Is config_options is a more suitable name

grizzled dawn
north knot
#

No its not

#

Its a seperate class

#

It dosent have to return toml::node_view

grizzled dawn
north knot
#

Yes

grizzled dawn
#
  toml::table tbl = toml::parse_file(static_config_path_t);
  auto logging = tbl["Logging"];
#

these all return node views

north knot
#

No

#

Config map is the file name

#

So its a std::string

#

Sort of

#

So it needs to be a toml::node type?

grizzled dawn
#

none of this is sort of! C++ is a compile time language, the types are important

#

the types determine everything about how something behaves

north knot
#

Yea but its a custom class

grizzled dawn
#

I can't tell you what a = 1 does unless I know the type of a

north knot
#

So config_path is variable file_t

#

Which is a custom enforced class

#

Pretty much just makes sure that whatever value is assigned is automatically checked so that its a valid file path

#

So you can pretty much translate config_map which is file_t to std::string

#

Its like std::string with extra steps

grizzled dawn
north knot
#

So how would you changed the map

#

To make it work

grizzled dawn
#

my issue is that I don't understand how this config map is instantiated or stored at all

north knot
#

The map is stored inside LoggingConfig

grizzled dawn
#

is ConfigValue a library?

north knot
#

Which the variables in the class is also stored in

north knot
#

class ConfigValue {
public:
/**
* @brief Type alias for supported configuration value types
/
using config_types = std::variant<bool, std::string_view, file_t, folder_t,
const char
, std::string>;
using config_map = std::unordered_map<std::string, config_types>;
/**
* @brief Default constructor
*/
ConfigValue() = default;

/**
 * @brief Constructor taking a configuration value
 */
template<typename T>
explicit ConfigValue(T&& value);

/**
 * @brief Copy constructor
 */
ConfigValue(const ConfigValue&) = default;

/**
 * @brief Move constructor
 */
ConfigValue(ConfigValue&&) noexcept = default;

/**
 * @brief Copy assignment operator
 */
ConfigValue& operator=(const ConfigValue&) = default;

/**
 * @brief Move assignment operator
 */
ConfigValue& operator=(ConfigValue&&) noexcept = default;

/**
 * @brief Assignment operator for config values
 */
ConfigValue& operator=(const config_types& value) {
    value_ = value;
    return *this;
}

/**
 * @brief Get the stored value
 */
[[nodiscard]] const config_types& value() const {
    return value_;
}

/**
* @oops what would this be used for?
*/
template<typename T>
[[nodiscard]] bool is() const;

template<typename T>
[[nodiscard]] const T& as() const;

protected:
config_types value_;
};

#

Not finnished

grizzled dawn
#

okay I still don't understand what you are trying to do

grizzled dawn
north knot
#

Yea im sorry mb

#

Pretty much

#

I need to loop through the map that holds a refrence to the class variables right?

#

And assign the values of the class variables

#

Through the map

#

If that works

grizzled dawn
#

I can't copy paste the code unless you edit it to be formatted

final robinBOT
#
How to Format Code on Discord
Markup

```cpp
int main() {}
```

Result
int main() {}
north knot
#

class ConfigValue {
public:
    /**
     * @brief Type alias for supported configuration value types
     */
    using config_types = std::variant<bool, std::string_view, file_t, folder_t,
                                     const char*, std::string>;
    using config_map = std::unordered_map<std::string, config_types>;
    /**
     * @brief Default constructor
     */
    ConfigValue() = default;

    /**
     * @brief Constructor taking a configuration value
     */
    template<typename T>
    explicit ConfigValue(T&& value);
    
    /**
     * @brief Copy constructor
     */
    ConfigValue(const ConfigValue&) = default;

    /**
     * @brief Move constructor
     */
    ConfigValue(ConfigValue&&) noexcept = default;

    /**
     * @brief Copy assignment operator
     */
    ConfigValue& operator=(const ConfigValue&) = default;

    /**
     * @brief Move assignment operator
     */
    ConfigValue& operator=(ConfigValue&&) noexcept = default;

    /**
     * @brief Assignment operator for config values
     */
    ConfigValue& operator=(const config_types& value) {
        value_ = value;
        return *this;
    }

    /**
     * @brief Get the stored value
     */
    [[nodiscard]] const config_types& value() const {
        return value_;
    }

    /**
    * @oops what would this be used for?
    */
    template<typename T>
    [[nodiscard]] bool is() const;
    
    template<typename T>
    [[nodiscard]] const T& as() const;

protected:
    config_types value_;
};
#


/** @note trouble fixing code*/
ConfigResult<ConfigValue> ConfigClass::LoggingConfig::load_config()const{
  toml::table tbl = toml::parse_file(static_config_path_t);
  auto logging = tbl["Logging"];
  for(auto& [name, value] : default_config){
    using value_decl_t = decltype(std::decay_t<value>);
    value = logging<value_decl_t>(name);
  }
}


grizzled dawn
#

okay std::unordered_map of std::variant is what I was fishing for

north knot
#

Yes

grizzled dawn
#

these are not holding references

north knot
#

So the map is not holding refrences to the class variables?

#

*class variables

grizzled dawn
#

the map holds references to the things in the map, but not to the sources it got them from

#

like yea, class variables

#

C++ is value typed by default

north knot
#

So how would you make the map directly represent the class variables?

grizzled dawn
#

bool is a bool value, bool& is a bool reference, bool* is a pointer (a reference value)

north knot
#

Yes I know

grizzled dawn
#

okay, but it seems like you don't understand the consequences of that if I understand what you are trying to do correctly

#

like your previous two messages are pretty contradictory

north knot
#

Yea...

#

I thought you could do this->variable_name which would mean that the variable stored was the classes

#

But I guess I missunderstood that

grizzled dawn
#

but the variant is storing the value

north knot
#

Okay yea

#

I understand what you mean

#

So how do you give it a value through the map instead of store one?

grizzled dawn
#

you don't want a value

#

you want a reference

north knot
#

Refrence yea

grizzled dawn
#

a reference binds to a variable.
passing values copies them

north knot
#

Mhm

grizzled dawn
#

the other problem you have is that decltype is not how you interact with a variant

north knot
#

I will fix that part later

grizzled dawn
#

okay well, it's like half of your main problem

north knot
#

Yea but its not as difficult for me to figure out

grizzled dawn
north knot
#

So youd want the map to contain & refrences to the class variables?

grizzled dawn
#

yes, or pointers

#

pointers are probably easier for you to use honestly

north knot
#

Okay and then youd do how?

grizzled dawn
#

references have a lot of pitfalls when one tries to use them for storage

#

rewrite the variant to use pointers

using config_types = std::variant<bool*, file_t*, folder_t*, std::string*>;

I removed two of them because they are basically just other ways to say the same thing and you shouldn't be using them for storage anyway.

#

then you change the config map thing

#

to bind to references

#
      const ConfigValue::config_map default_config = {
        {"Log-path", &log_path},
        {"Username", &this->username},
        {"User-ID", &this->user_id},
        {"User-profile", &this->user_profile},
        {"Message", &this->message},
        {"Message-Timestamp", &message_timestamp}
    };
#

note the &

north knot
#

Yes okay

#

Thank you

#

!solved

final robinBOT
#

Thank you and let us know if you have any more questions!

This thread is now set to auto-hide after an hour of inactivity

grizzled dawn
#

FWIW this is basically a "writing your own reflection library" path you are walking.

#

but this is also why I usually write my own, rarely does my problem require a fully fledged library

north knot
#

I see