#ifndef AOS_UTIL_OPTIONS_H_
#define AOS_UTIL_OPTIONS_H_

#include <sys/types.h>

namespace aos {

template <class Owner>
class Options;

// An "option" that can be combined with other options and passed as one
// argument. This class is designed to emulate integral constants (except be
// type-safe), so its instances can be combined with operator| (creating an
// Options), and an Options can be tested for membership with operator&.
// Owner is the only class that can construct Option instances and is used to
// differentiate between options for different classes. It is safe to only have
// a forward declaration for Owner in scope when instantiating either of these
// template classes.
template <class Owner>
class Options {
 public:
  // Represents a single options. Instances of this should be created as
  // constants by Owner.
  class Option {
   public:
    constexpr Options operator|(Option option) const {
      return Options(bit_ | option.bit_);
    }

    constexpr bool operator==(Option other) const { return bit_ == other.bit_; }

    constexpr unsigned int printable() const { return bit_; }

   private:
    // Bit must have exactly 1 bit set and that must be a different one for each
    // instance.
    explicit constexpr Option(unsigned int bit) : bit_(bit) {}

    unsigned int bit_;

    friend class Options;
    friend Owner;
  };

  constexpr Options(Option option) : bits_(option.bit_) {}

  constexpr bool operator&(Option option) const {
    return (bits_ & option.bit_) != 0;
  }

  constexpr Options operator|(Option option) const {
    return Options(bits_ | option.bit_);
  }
  constexpr Options operator|(Options options) const {
    return Options(bits_ | options.bits_);
  }

  constexpr bool operator==(Options other) const {
    return bits_ == other.bits_;
  }

  constexpr unsigned int printable() const { return bits_; }

  // Returns true if no Options other than the ones in options are set.
  // Useful for validating that no illegal options are passed.
  constexpr bool NoOthersSet(Options options) const {
    return (bits_ & ~options.bits_) == 0;
  }

  // Returns true if exactly 1 of the Options in options is set.
  // Useful for validating that one of a group of mutually exclusive options has
  // been passed.
  constexpr bool ExactlyOneSet(Options options) const {
    return __builtin_popcount(bits_ & options.bits_) == 1;
  }

  // Returns true if all of the Options in options are set.
  constexpr bool AllSet(Options options) const {
    return (bits_ & options.bits_) == options.bits_;
  }

 private:
  explicit constexpr Options(unsigned int bits) : bits_(bits) {}

  unsigned int bits_;

  friend class Option;
};

}  // namespace options

#endif  // AOS_UTIL_OPTIONS_H_
