Jul 18, 2022

[C++][note] union tagging sample code

#include <new>
#include <string>

constexpr int TU_STRING = 0;
constexpr int TU_INT = 1;
constexpr int TU_FLOAT = 2;

struct TU {
  union my_union {
    struct i_type {
      int type;
      int i;
    } i;
    
    struct f_type {
      int type;
      float f;
    } f;
    
    struct s_type {
      int type;
      std::string s;
    } s;

    my_union(int i) : i{TU_INT, i} {}
    my_union(float f) : f{TU_FLOAT, f} {}
    my_union(std::string s) : s{TU_STRING, std::move(s)} {}
    my_union(my_union const &other) {
      // This is safe.
      switch (other.i.type) {
      case TU_INT:
        ::new (&i) auto(other.i);
        break;
      case TU_FLOAT:
        ::new (&f) auto(other.f);
        break;
      case TU_STRING:
        ::new (&s) auto(other.s);
        break;
      }
    }
    
    ~my_union() {
      // This is safe.
      if (TU_STRING == s.type) {
        s.~s_type();
      }
    }
  } u;

  TU(int i) : u(i) {}
  TU(float f) : u(f) {}
  TU(std::string s) : u(std::move(s)) {}
  TU(TU const &) = default;
  ~TU() = default;
};

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.