Add classes needed for weekday_selector

This commit is contained in:
Sergey Magidovich 2015-10-21 14:10:58 +03:00
parent 5631638b9d
commit 101de51db2
2 changed files with 456 additions and 24 deletions

View file

@ -29,6 +29,36 @@
#include <cstdlib>
#include <codecvt>
namespace
{
template <typename T>
void print_vector(std::ostream & ost, std::vector<T> const & v)
{
auto it = begin(v);
if (it == end(v))
return;
ost << *it++;
while(it != end(v))
{
ost << ',' << *it++;
}
}
void print_offset(std::ostream & ost, int32_t const offset)
{
if (offset == 0)
return;
ost << ' ';
if (offset > 0)
ost << '+';
ost << offset;
ost << ' ' << "day";
if (std::abs(offset) > 1)
ost << 's';
}
} // namespace
namespace osmoh
{
@ -274,15 +304,291 @@ std::ostream & operator<<(std::ostream & ost, Timespan const & span)
std::ostream & operator<<(std::ostream & ost, osmoh::TTimespans const & timespans)
{
auto it = begin(timespans);
ost << *it++;
while(it != end(timespans))
print_vector(ost, timespans);
return ost;
}
bool NthEntry::IsEmpty() const
{
return !HasStart() && !HasEnd();
}
bool NthEntry::HasStart() const
{
return GetStart() != ENth::None;
}
bool NthEntry::HasEnd() const
{
return GetEnd() != ENth::None;
}
NthEntry::ENth NthEntry::GetStart() const
{
return m_start;
}
NthEntry::ENth NthEntry::GetEnd() const
{
return m_end;
}
void NthEntry::SetStart(ENth const s)
{
m_start = s;
}
void NthEntry::SetEnd(ENth const e)
{
m_end = e;
}
std::ostream & operator<<(std::ostream & ost, NthEntry const entry)
{
if (entry.HasStart())
ost << static_cast<uint32_t>(entry.GetStart());
if (entry.HasEnd())
ost << '-' << static_cast<uint32_t>(entry.GetEnd());
return ost;
}
bool WeekdayRange::HasWday(EWeekday const & wday) const
{
if (IsEmpty() || wday == EWeekday::None)
return false;
if (!HasEnd())
return GetStart() == wday;
return GetStart() <= wday && wday <= GetEnd();
}
bool WeekdayRange::HasSu() const { return HasWday(Su); }
bool WeekdayRange::HasMo() const { return HasWday(Mo); }
bool WeekdayRange::HasTu() const { return HasWday(Tu); }
bool WeekdayRange::HasWe() const { return HasWday(We); }
bool WeekdayRange::HasTh() const { return HasWday(Th); }
bool WeekdayRange::HasFr() const { return HasWday(Fr); }
bool WeekdayRange::HasSa() const { return HasWday(Sa); }
bool WeekdayRange::HasStart() const
{
return GetStart() != EWeekday::None;
}
bool WeekdayRange::HasEnd() const
{
return GetEnd() != EWeekday::None;;
}
bool WeekdayRange::IsEmpty() const
{
return GetStart() == EWeekday::None && GetEnd() == EWeekday::None;
}
WeekdayRange::EWeekday WeekdayRange::GetStart() const
{
return m_start;
}
WeekdayRange::EWeekday WeekdayRange::GetEnd() const
{
return m_end;
}
size_t WeekdayRange::GetDaysCount() const
{
if (IsEmpty())
return 0;
return m_start - m_end + 1;
}
void WeekdayRange::SetStart(EWeekday const & wday)
{
m_start = wday;
}
void WeekdayRange::SetEnd(EWeekday const & wday)
{
m_end = wday;
}
int32_t WeekdayRange::GetOffset() const
{
return m_offset;
}
void WeekdayRange::SetOffset(int32_t const offset)
{
m_offset = offset;
}
bool WeekdayRange::HasNth() const
{
return !m_nths.empty();
}
WeekdayRange::TNths const & WeekdayRange::GetNths() const
{
return m_nths;
}
void WeekdayRange::AddNth(NthEntry const & entry)
{
m_nths.push_back(entry);
}
std::ostream & operator<<(std::ostream & ost, WeekdayRange::EWeekday const wday)
{
switch(wday)
{
ost << ',' << *it++;
case WeekdayRange::EWeekday::Su:
ost << "Su";
break;
case WeekdayRange::EWeekday::Mo:
ost << "Mo";
break;
case WeekdayRange::EWeekday::Tu:
ost << "Tu";
break;
case WeekdayRange::EWeekday::We:
ost << "We";
break;
case WeekdayRange::EWeekday::Th:
ost << "Th";
break;
case WeekdayRange::EWeekday::Fr:
ost << "Fr";
break;
case WeekdayRange::EWeekday::Sa:
ost << "Sa";
break;
case WeekdayRange::EWeekday::None:
ost << "not-a-day";
}
return ost;
}
std::ostream & operator<<(std::ostream & ost, WeekdayRange const & range)
{
ost << range.GetStart();
if (range.HasEnd())
ost << '-' << range.GetEnd();
else
{
if (range.HasNth())
{
print_vector(ost, range.GetNths());
}
print_offset(ost, range.GetOffset());
}
return ost;
}
std::ostream & operator<<(std::ostream & ost, TWeekdayRanges const & ranges)
{
print_vector(ost, ranges);
return ost;
}
bool Holiday::IsPlural() const
{
return m_plural;
}
void Holiday::SetPlural(bool const plural)
{
m_plural = plural;
}
int32_t Holiday::GetOffset() const
{
return m_offset;
}
void Holiday::SetOffset(int32_t const offset)
{
m_offset = offset;
}
std::ostream & operator<<(std::ostream & ost, Holiday const & holiday)
{
if (holiday.IsPlural())
ost << "PH";
else
{
ost << "SH";
print_offset(ost, holiday.GetOffset());
}
return ost;
}
std::ostream & operator<<(std::ostream & ost, THolidays const & holidays)
{
print_vector(ost, holidays);
return ost;
}
bool Weekdays::HasWeekday() const
{
return !GetWeekdayRanges().empty();
}
bool Weekdays::HasHolidays() const
{
return !GetHolidays().empty();
}
TWeekdayRanges const & Weekdays::GetWeekdayRanges() const
{
return m_weekdayRanges;
}
THolidays const & Weekdays::GetHolidays() const
{
return m_holidays;
}
void Weekdays::SetWeekdayRanges(TWeekdayRanges const ranges)
{
m_weekdayRanges = ranges;
}
void Weekdays::SetHolidays(THolidays const & holidays)
{
m_holidays = holidays;
}
void Weekdays::AddWeekdayRange(WeekdayRange const range)
{
m_weekdayRanges.push_back(range);
}
void Weekdays::AddHoliday(Holiday const & holiday)
{
m_holidays.push_back(holiday);
}
std::ostream & operator<<(std::ostream & ost, Weekdays const & weekday)
{
ost << weekday.GetHolidays();
if (weekday.HasWeekday() && weekday.HasHolidays())
ost << ',';
ost << weekday.GetWeekdayRanges();
return ost;
}
std::ostream & operator<<(std::ostream & ost, TWeekdayss const & weekdays)
{
print_vector(ost, weekdays);
return ost;
}
// std::ostream & operator << (std::ostream & s, Weekday const & w)
// {
// static char const * wdays[] = {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"};

View file

@ -32,12 +32,6 @@
namespace osmoh
{
class Weekday;
class Timespan;
class TimeRule;
using TWeekdays = std::vector<Weekday>;
using TTimespans = std::vector<Timespan>;
class Time
{
@ -48,6 +42,8 @@ class Time
eHaveMinutes = 2,
};
using TEStateRep = std::underlying_type<EState>::type;
public:
enum class EEvent
{
@ -99,7 +95,7 @@ class Time
private:
EEvent m_event{EEvent::eNotEvent};
TMinutes m_duration{TMinutes::zero()};
std::underlying_type<EState>::type m_state{EState::eIsNotTime};
TEStateRep m_state{EState::eIsNotTime};
};
inline constexpr Time::THours operator ""_h(unsigned long long h)
@ -146,23 +142,153 @@ class Timespan
bool m_plus{false};
};
using TTimespans = std::vector<Timespan>;
std::ostream & operator<<(std::ostream & ost, Timespan const & span);
std::ostream & operator<<(std::ostream & ost, osmoh::TTimespans const & timespans);
class NthEntry
{
public:
enum class ENth
{
None,
First,
Second,
Third,
Fourth,
Fifth
};
public:
bool IsEmpty() const;
bool HasStart() const;
bool HasEnd() const;
ENth GetStart() const;
ENth GetEnd() const;
void SetStart(ENth const s);
void SetEnd(ENth const e);
private:
ENth m_start{};
ENth m_end{};
};
std::ostream & operator<<(std::ostream & ost, NthEntry const entry);
class WeekdayRange
{
using TNths = std::vector<NthEntry>;
public:
enum EWeekday
{
None,
Su,
Mo,
Tu,
We,
Th,
Fr,
Sa
};
public:
bool HasWday(EWeekday const & wday) const;
bool HasSu() const;
bool HasMo() const;
bool HasTu() const;
bool HasWe() const;
bool HasTh() const;
bool HasFr() const;
bool HasSa() const;
bool HasStart() const;
bool HasEnd() const;
bool IsEmpty() const;
EWeekday GetStart() const;
EWeekday GetEnd() const;
size_t GetDaysCount() const;
void SetStart(EWeekday const & wday);
void SetEnd(EWeekday const & wday);
int32_t GetOffset() const;
void SetOffset(int32_t const offset);
bool HasNth() const;
TNths const & GetNths() const;
void AddNth(NthEntry const & entry);
private:
EWeekday m_start{};
EWeekday m_end{};
int32_t m_offset{};
TNths m_nths;
};
inline constexpr WeekdayRange::EWeekday operator ""_day(unsigned long long day)
{
return ((day <= WeekdayRange::EWeekday::None || day > WeekdayRange::EWeekday::Sa)
? WeekdayRange::EWeekday::None
: static_cast<WeekdayRange::EWeekday>(day));
}
using TWeekdayRanges = std::vector<WeekdayRange>;
std::ostream & operator<<(std::ostream & ost, WeekdayRange::EWeekday const wday);
std::ostream & operator<<(std::ostream & ost, WeekdayRange const & range);
std::ostream & operator<<(std::ostream & ost, TWeekdayRanges const & ranges);
class Holiday
{
public:
bool IsPlural() const;
void SetPlural(bool const plural);
int32_t GetOffset() const;
void SetOffset(int32_t const offset);
private:
bool m_plural{false};
int32_t m_offset{};
};
using THolidays = std::vector<Holiday>;
std::ostream & operator<<(std::ostream & ost, Holiday const & holiday);
std::ostream & operator<<(std::ostream & ost, THolidays const & holidys);
class Weekdays // Correspond to weekday_selector in osm opening hours
{
public:
bool HasWeekday() const;
bool HasHolidays() const;
TWeekdayRanges const & GetWeekdayRanges() const;
THolidays const & GetHolidays() const;
void SetWeekdayRanges(TWeekdayRanges const ranges);
void SetHolidays(THolidays const & holidays);
void AddWeekdayRange(WeekdayRange const range);
void AddHoliday(Holiday const & holiday);
private:
TWeekdayRanges m_weekdayRanges;
THolidays m_holidays;
};
using TWeekdayss = std::vector<Weekdays>; // TODO(mgsergio): make up a better name
std::ostream & operator<<(std::ostream & ost, Weekdays const & weekday);
} // namespace osmoh
// class Weekday
// {
// public:
// uint8_t weekdays;
// uint16_t nth;
// int32_t offset;
// Weekday() : weekdays(0), nth(0), offset(0) {}
// std::string ToString() const;
// friend std::ostream & operator << (std::ostream & s, Weekday const & w);
// };
// class State
// {
// public: