AceTime  3.0.0
Date and time classes for Arduino that support timezones from the TZ Database.
ZoneSorterByOffsetAndName.h
1 /*
2  * MIT License
3  * Copyright (c) 2021 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_ZONE_SORTER_BY_OFFSET_AND_NAME_H
7 #define ACE_TIME_ZONE_SORTER_BY_OFFSET_AND_NAME_H
8 
9 #include <AceSorting.h>
10 #include "ZoneManager.h"
11 
12 namespace ace_time {
13 
21 template <typename ZM>
23  public:
28  ZoneSorterByOffsetAndName(const ZM& zoneManager) :
29  mZoneManager(zoneManager)
30  {}
31 
36  void fillIndexes(uint16_t indexes[], uint16_t size) const {
37  for (uint16_t i = 0; i < size; i++) {
38  indexes[i] = i;
39  }
40  }
41 
43  void sortIndexes(uint16_t indexes[], uint16_t size) const {
44  ace_sorting::shellSortKnuth(indexes, size,
45  [this](uint16_t indexA, uint16_t indexB) -> bool {
46  auto za = this->mZoneManager.getZoneForIndex(indexA);
47  auto zb = this->mZoneManager.getZoneForIndex(indexB);
48  return this->compareZone(za, zb) < 0;
49  }
50  );
51  }
52 
54  void sortIds(uint32_t ids[], uint16_t size) const {
55  ace_sorting::shellSortKnuth(ids, size,
56  [this](uint32_t a, uint32_t b) -> bool {
57  uint16_t indexA = this->mZoneManager.indexForZoneId(a);
58  uint16_t indexB = this->mZoneManager.indexForZoneId(b);
59  auto za = this->mZoneManager.getZoneForIndex(indexA);
60  auto zb = this->mZoneManager.getZoneForIndex(indexB);
61  return this->compareZone(za, zb) < 0;
62  }
63  );
64  }
65 
67  void sortNames(const char* names[], uint16_t size) const {
68  ace_sorting::shellSortKnuth(names, size,
69  [this](const char* a, const char* b) -> bool {
70  uint16_t indexA = this->mZoneManager.indexForZoneName(a);
71  uint16_t indexB = this->mZoneManager.indexForZoneName(b);
72  auto za = this->mZoneManager.getZoneForIndex(indexA);
73  auto zb = this->mZoneManager.getZoneForIndex(indexB);
74  return this->compareZone(za, zb) < 0;
75  }
76  );
77  }
78 
89  template <typename Z>
90  static int compareZone(const Z& a, const Z& b) {
91  if (a.isNull()) {
92  if (b.isNull()) {
93  return 0;
94  } else {
95  return -1;
96  }
97  }
98  if (b.isNull()) return 1;
99 
100  TimeOffset offsetA = a.stdOffset();
101  TimeOffset offsetB = b.stdOffset();
102  if (offsetA.toSeconds() < offsetB.toSeconds()) return -1;
103  if (offsetA.toSeconds() > offsetB.toSeconds()) return 1;
104  return a.kname().compareTo(b.kname());
105  }
106 
107  private:
108  // disable copy constructor and assignment operator
111  = delete;
112 
113  private:
114  const ZM& mZoneManager;
115 };
116 
117 }
118 
119 #endif
A thin wrapper that represents a time offset from a reference point, usually 00:00 at UTC,...
Definition: TimeOffset.h:56
int32_t toSeconds() const
Return the time offset as seconds.
Definition: TimeOffset.h:131
ZoneSorterByOffsetAndName, templatized on a ZoneManager (BasicZoneManager, ExtendedZoneManager,...
void sortIndexes(uint16_t indexes[], uint16_t size) const
Sort the given array of indexes by UTC offset, then by name.
static int compareZone(const Z &a, const Z &b)
Return <0, 0, or >0 depending on whether Zone a is <, ==, or > than Zone b.
void fillIndexes(uint16_t indexes[], uint16_t size) const
Fill the given array of indexes with index from [0, size).
void sortIds(uint32_t ids[], uint16_t size) const
Sort the given array of zone ids by UTC offset, then by name.
ZoneSorterByOffsetAndName(const ZM &zoneManager)
Constructor.
void sortNames(const char *names[], uint16_t size) const
Sort the given array of zone names by UTC offset, then by name.