Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending enum types [duplicate]

Tags:

c++

enums

Possible Duplicate:
Extending enums in C++?

I am using a library which defines its own set of errors as an enum type.

enum error_type {...}

The library also has a function which takes that enum type, and prints the error.

void set_status(error_type new_error)

If I want to define my own error, and give it to the set_status function, is it possible to extend the error_type enum somehow, or maybe override it?

like image 345
marcwho Avatar asked Jan 24 '13 14:01

marcwho


People also ask

Can enum have duplicate values?

CA1069: Enums should not have duplicate values.

Is it possible to extend an enum?

The short answer is no, you can't extend enums because TypeScript offers no language feature to extend them. However, there are workarounds you can utilize to achieve what inheritance would.

Can enums be dynamic?

But can one even make Enums dynamic? # Enums, by definition, are static. They are used to “predefine” constants.

Can enums extend abstract classes?

Enum cannot extend any class in java,the reason is, by default Enum extends abstract base class java. lang. Enum. Since java does not support multiple inheritance for classes, Enum can not extend another class.


1 Answers

There might be some sharp edges, but I think this should work for you:

#include<iostream>

// Helper struct

template<typename T, int N, typename... LIST>
struct whereInType {
  static const int index = -1;
};

template<typename T, int N, typename HEAD, typename... TAIL>
struct whereInType<T,N,HEAD,TAIL...> {
  static const int index = whereInType<T, N+1, TAIL...>::index;
};

template<typename T, int N, typename... TAIL>
struct whereInType<T,N,T,TAIL...> {
  static const int index = N;
};

// The actual union type

template<typename... ENUMS>
class enum_union {
public:
  template<typename ENUM>
  constexpr enum_union(ENUM val) :
    which_enum(whereInType<ENUM,0,ENUMS...>::index),
    value(val) {}
  constexpr operator long long(){
    return static_cast<long long>(which_enum)<<32 | value;
  }
  template<typename ENUM, int IGNORE=0>
  constexpr bool operator==(const ENUM& e) {
    return *this == enum_union<ENUMS...>(e);
  }
  template<int IGNORE=0>
  constexpr bool operator==(const enum_union<ENUMS...>& oth) {
    return which_enum==oth.which_enum && value==oth.value;
  }
  template<typename T>
  constexpr bool operator!=(const T& oth) {
    return !(*this == oth);
  }
private:
  int which_enum;
  int value;
};

// An example usage

enum normal_errors {
  E_OUTOFMEMORY,
  E_IOERROR
};

enum weird_errors {
  E_OUTOFAARDVARKS,
  E_DIVIDEBYCUCUMBER
};

typedef enum_union<normal_errors, weird_errors> any_error;

// Some tests

void print(any_error e) {
  switch(e) {
  case any_error(E_OUTOFMEMORY):
    std::cout << "Out of Memory\n";
    break;
  case any_error(E_IOERROR):
    std::cout << "I/O Error\n";
    break;
  case any_error(E_OUTOFAARDVARKS):
    std::cout << "WE NEED AARDVARKS!!!  NOW!!!!!\n";
    break;
  case any_error(E_DIVIDEBYCUCUMBER):
    std::cout << "please reinstall universe\n";
    break;
  }
}  

main(){
  print(E_OUTOFMEMORY);
  print(E_IOERROR);
  print(E_OUTOFAARDVARKS);
  print(E_DIVIDEBYCUCUMBER);
  if (any_error(E_OUTOFMEMORY) == E_OUTOFAARDVARKS) {
    std::cout<<"bad\n";
  }else{
    std::cout<<"good\n";
  }
  if (any_error(E_OUTOFMEMORY) != E_OUTOFAARDVARKS) {
    std::cout<<"good\n";
  }else{
    std::cout<<"bad\n";
  }
  if (any_error(E_OUTOFMEMORY) == E_OUTOFMEMORY) {
    std::cout<<"good\n";
  }else{
    std::cout<<"bad\n";
  }
  if (any_error(E_OUTOFMEMORY) != E_OUTOFMEMORY) {
    std::cout<<"bad\n";
  }else{
    std::cout<<"good\n";
  }
}
like image 56
dspeyer Avatar answered Sep 24 '22 02:09

dspeyer