text: /**
   * @file Address.h
   * @date 2021-6-1
   * @author kaoru
   * @brief 地址类基类头文件
   */
  
  #ifndef ZFRAMEWORK_ADDRESS_H
  #define ZFRAMEWORK_ADDRESS_H
  
  #include <netdb.h>
  #include <memory>
  #include <sys/socket.h>
  #include <vector>
  #include <string>
  #include <map>
  #include <ifaddrs.h>
  #include "Macro.h"
  
  namespace ZFramework {
  
      template<class T>
      static T CreateMask(uint32_t bits) {
          return (1 << (sizeof(T) * 8 - bits)) - 1;
      }
  
      template<class T>
      static uint32_t CountBytes(T t) {
          uint32_t res = 0;
          for (; t; res++) {
              t &= t - 1;
          }
          return res;
      }
  
      class Address {
      public:
          typedef std::shared_ptr<Address> ptr;
  
          static Address::ptr Create(const sockaddr *address, socklen_t addrlen);
  
          static bool Lookup(std::vector<Address::ptr> &result,
                             const std::string &host,
                             int family = AF_INET,
                             int type = 0,
                             int protocol = 0
                            );
  
          static Address::ptr LookUpAny(const std::string &host,
                                        int family = AF_INET,
                                        int type = 0,
                                        int protocol = 0
                                       );
  
          static Address::ptr LookupAnyIPAddress(const std::string &host,
                                                 int family = AF_INET,
                                                 int type = 0,
                                                 int protocol = 0
                                                );
  
          static bool GetInterfaceAddresses(std::multimap<std::string, std::pair<Address::ptr, uint32_t>> &result,
                                            int family = AF_INET
                                           );
  
          static bool GetInterfaceAddresses(std::vector<std::pair<Address::ptr, uint32_t>> &result,
                                            const std::string &iface,
                                            int family = AF_INET
                                           );
  
          virtual ~Address() = default;
  
      public:
  
          int getFamily() const;
  
          virtual const sockaddr *getAddress() const = 0;
  
          virtual sockaddr *getAddress() = 0;
  
          virtual socklen_t getAddressLength() const = 0;
  
          virtual std::ostream &insert(std::ostream &os) const = 0;
  
          std::string toString() const;
  
      public:
  
          bool operator<(const Address &rhs) const;
  
          bool operator==(const Address &rhs) const;
  
          bool operator!=(const Address &rhs) const;
  
      private:
      };
  
  }// ZFramework
  
  #endif //ZFRAMEWORK_ADDRESS_H
  