Code review

This commit is contained in:
Sergey Magidovich 2015-11-16 12:42:30 +03:00
parent 7de510b787
commit bb9cdee103
6 changed files with 137 additions and 110 deletions

View file

@ -35,7 +35,7 @@
namespace
{
template <typename T, typename SeparatorExtractor>
inline void PrintVector(std::ostream & ost, std::vector<T> const & v,
void PrintVector(std::ostream & ost, std::vector<T> const & v,
SeparatorExtractor && sepFunc)
{
auto it = begin(v);
@ -53,12 +53,12 @@ inline void PrintVector(std::ostream & ost, std::vector<T> const & v,
}
template <typename T>
inline void PrintVector(std::ostream & ost, std::vector<T> const & v, char const * const sep = ", ")
void PrintVector(std::ostream & ost, std::vector<T> const & v, char const * const sep = ", ")
{
PrintVector(ost, v, [&sep](T const &) { return sep; });
}
inline void PrintOffset(std::ostream & ost, int32_t const offset, bool const space)
void PrintOffset(std::ostream & ost, int32_t const offset, bool const space)
{
if (offset == 0)
return;
@ -92,15 +92,13 @@ class StreamFlagsKeeper
std::ios_base::fmtflags m_flags;
};
inline void PrintPaddedNumber(std::ostream & ost,
uint32_t const number,
uint32_t const padding = 1)
void PrintPaddedNumber(std::ostream & ost, uint32_t const number, uint32_t const padding = 1)
{
StreamFlagsKeeper keeper(ost);
ost << std::setw(padding) << std::setfill('0') << number;
}
inline void PrintHoursMinutes(std::ostream & ost,
void PrintHoursMinutes(std::ostream & ost,
std::chrono::hours::rep hours,
std::chrono::minutes::rep minutes)
{
@ -108,10 +106,12 @@ inline void PrintHoursMinutes(std::ostream & ost,
ost << ':';
PrintPaddedNumber(ost, minutes, 2);
}
} // namespace
namespace osmoh
{
// HourMinutes -------------------------------------------------------------------------------------
HourMinutes::HourMinutes(THours const duration)
{
@ -491,18 +491,21 @@ bool Timespan::HasPeriod() const
bool Timespan::HasExtendedHours() const
{
if (HasStart() && HasEnd() &&
GetStart().IsHoursMinutes() &&
GetEnd().IsHoursMinutes())
bool const canHaveExtendedHours = HasStart() && HasEnd() &&
GetStart().IsHoursMinutes() &&
GetEnd().IsHoursMinutes();
if (!canHaveExtendedHours)
{
auto const & startHM = GetStart().GetHourMinutes();
auto const & endHM = GetEnd().GetHourMinutes();
if (endHM.IsExtended())
return true;
return endHM.GetDurationCount() != 0 && (endHM.GetDuration() < startHM.GetDuration());
return false;
}
return false;
auto const & startHM = GetStart().GetHourMinutes();
auto const & endHM = GetEnd().GetHourMinutes();
if (endHM.IsExtended())
return true;
return endHM.GetDurationCount() != 0 && (endHM.GetDuration() < startHM.GetDuration());
}
Time const & Timespan::GetStart() const

View file

@ -14,7 +14,7 @@
namespace
{
template <typename T>
inline std::string ToString(T const & t)
std::string ToString(T const & t)
{
std::stringstream sstr;
sstr << t;
@ -22,20 +22,20 @@ inline std::string ToString(T const & t)
}
template <typename T>
inline bool HasPeriod(std::vector<T> const & v)
bool HasPeriod(std::vector<T> const & v)
{
auto const hasPeriod = [](T const & t) { return t.HasPeriod(); };
return std::any_of(begin(v), end(v), hasPeriod);
}
template <typename T>
inline bool HasPlus(std::vector<T> const & v)
bool HasPlus(std::vector<T> const & v)
{
auto const hasPlus = [](T const & t) { return t.HasPlus(); };
return std::any_of(begin(v), end(v), hasPlus);
}
inline bool HasOffset(osmoh::TMonthdayRanges const & mr)
bool HasOffset(osmoh::TMonthdayRanges const & mr)
{
auto const hasOffset = [](osmoh::MonthdayRange const & md) {
return
@ -45,14 +45,14 @@ inline bool HasOffset(osmoh::TMonthdayRanges const & mr)
return std::any_of(begin(mr), end(mr), hasOffset);
}
inline bool HasOffset(osmoh::Weekdays const & wd)
bool HasOffset(osmoh::Weekdays const & wd)
{
auto const hasOffset = [](osmoh::WeekdayRange const & w) { return w.HasOffset(); };
return std::any_of(begin(wd.GetWeekdayRanges()), end(wd.GetWeekdayRanges()), hasOffset);
}
template <typename ParserResult>
inline bool CompareNormalized(std::string const & original, ParserResult const & pretendent)
bool CompareNormalized(std::string const & original, ParserResult const & pretendent)
{
auto originalCopy = original;
auto pretendentCopy = ToString(pretendent);
@ -79,13 +79,13 @@ enum
};
using TRuleFeatures = std::array<bool, Count_>;
inline std::ostream & operator<<(std::ostream & ost, TRuleFeatures const & f)
std::ostream & operator<<(std::ostream & ost, TRuleFeatures const & f)
{
std::copy(begin(f), end(f), std::ostream_iterator<bool>(ost, "\t"));
return ost;
}
inline TRuleFeatures DescribeRule(osmoh::TRuleSequences const & rule)
TRuleFeatures DescribeRule(osmoh::TRuleSequences const & rule)
{
TRuleFeatures features{};
for (auto const & r : rule)

View file

@ -11,7 +11,7 @@ namespace
typedef std::tuple<long, long> LongTimeRange;
int countTests = 0;
inline LongTimeRange RangeToLong(std::string const & start, std::string const & end)
LongTimeRange RangeToLong(std::string const & start, std::string const & end)
{
std::tm when{};
@ -25,10 +25,9 @@ inline LongTimeRange RangeToLong(std::string const & start, std::string const &
}
inline void TestRanges(std::string const & name,
std::initializer_list<std::string> const & strings,
std::string const & rangeStart, std::string const & rangeEnd,
std::initializer_list<std::vector<std::string>> const & ranges)
void TestRanges(std::string const & name, std::initializer_list<std::string> const & strings,
std::string const & rangeStart, std::string const & rangeEnd,
std::initializer_list<std::vector<std::string>> const & ranges)
{
for (std::string const & input : strings)
{
@ -92,7 +91,7 @@ inline void TestRanges(std::string const & name,
}
}
inline void TestShouldFail(std::string const & name, std::initializer_list<std::string> const & strings)
void TestShouldFail(std::string const & name, std::initializer_list<std::string> const & strings)
{
for (std::string const & input : strings)
{

View file

@ -47,7 +47,7 @@
namespace
{
template <typename T>
inline std::string ToString(T const & t)
std::string ToString(T const & t)
{
std::stringstream sstr;
sstr << t;
@ -55,7 +55,7 @@ inline std::string ToString(T const & t)
}
template <typename Parser>
inline bool Test(std::string const & str, Parser const & p, bool full_match = true)
bool Test(std::string const & str, Parser const & p, bool full_match = true)
{
// We don't care about the result of the "what" function.
// We only care that all parsers have it:
@ -67,7 +67,7 @@ inline bool Test(std::string const & str, Parser const & p, bool full_match = tr
}
template <typename ParseResult>
inline std::string ParseAndUnparse(std::string const & str)
std::string ParseAndUnparse(std::string const & str)
{
ParseResult parseResult;
if (!osmoh::Parse(str, parseResult))
@ -79,7 +79,7 @@ inline std::string ParseAndUnparse(std::string const & str)
return sstr.str();
}
inline bool GetTimeTuple(std::string const & strTime, std::string const & fmt, std::tm & tm)
bool GetTimeTuple(std::string const & strTime, std::string const & fmt, std::tm & tm)
{
auto const rc = strptime(strTime.data(), fmt.data(), &tm);
return rc != nullptr;
@ -95,7 +95,7 @@ struct GetTimeError: std::exception
std::string const m_message;
};
inline osmoh::RuleState GetRulesState(osmoh::TRuleSequences const & rules, std::string const & dateTime)
osmoh::RuleState GetRulesState(osmoh::TRuleSequences const & rules, std::string const & dateTime)
{
static auto const & fmt = "%Y-%m-%d %H:%M";
std::tm time = {};
@ -107,22 +107,22 @@ inline osmoh::RuleState GetRulesState(osmoh::TRuleSequences const & rules, std::
return osmoh::GetState(rules, mktime(&time));
}
inline bool IsOpen(osmoh::TRuleSequences const & rules, std::string const & dateTime)
bool IsOpen(osmoh::TRuleSequences const & rules, std::string const & dateTime)
{
return GetRulesState(rules, dateTime) == osmoh::RuleState::Open;
}
inline bool IsClosed(osmoh::TRuleSequences const & rules, std::string const & dateTime)
bool IsClosed(osmoh::TRuleSequences const & rules, std::string const & dateTime)
{
return GetRulesState(rules, dateTime) == osmoh::RuleState::Closed;
}
inline bool IsUnknown(osmoh::TRuleSequences const & rules, std::string const & dateTime)
bool IsUnknown(osmoh::TRuleSequences const & rules, std::string const & dateTime)
{
return GetRulesState(rules, dateTime) == osmoh::RuleState::Unknown;
}
inline bool IsActive(osmoh::RuleSequence const & rule, std::tm tm)
bool IsActive(osmoh::RuleSequence const & rule, std::tm tm)
{
return IsActive(rule, mktime(&tm));
}
@ -1286,18 +1286,6 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TestIsActive)
BOOST_CHECK(GetTimeTuple("2015 14 3", fmt, time));
BOOST_CHECK(!IsActive(ranges[0], time));
}
{
TRuleSequences rules;
BOOST_CHECK(Parse("Mo-We 17:00-18:00, Th,Fr 15:00-16:00", rules));
std::tm time{};
auto const fmt = "%Y-%m-%d %H:%M";
BOOST_CHECK(GetTimeTuple("2015-10-6 17:35", fmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-10-8 15:35", fmt, time));
BOOST_CHECK(IsActive(rules[1], time));
}
{
TRuleSequences rules;
BOOST_CHECK(Parse("09:00-14:00", rules));
@ -1312,41 +1300,73 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TestIsActive)
}
{
TRuleSequences rules;
BOOST_CHECK(Parse("Apr-Sep Su 14:30-17:00", rules));
BOOST_CHECK(Parse("Mo-We 17:00-18:00, Th,Fr 15:00-16:00", rules));
std::tm time{};
auto const fmt = "%Y-%m-%d %H:%M";
BOOST_CHECK(GetTimeTuple("2015-04-12 15:35", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-10-6 17:35", fmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-04-13 15:35", fmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-10-11 15:35", fmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-10-8 15:35", fmt, time));
BOOST_CHECK(IsActive(rules[1], time));
}
auto const kDateTimeFmt = "%Y-%m-%d %H:%M";
{
TRuleSequences rules;
BOOST_CHECK(Parse("2010 Apr 01-30: Mo-Su 17:00-24:00", rules));
std::tm time{};
auto const fmt = "%Y-%m-%d-%w %H:%M";
BOOST_CHECK(GetTimeTuple("2010-4-20-0 18:15", fmt, time));
BOOST_CHECK(GetTimeTuple("2010-4-20 18:15", kDateTimeFmt, time));
BOOST_CHECK(IsActive(rules[0], time));
}
{
TRuleSequences rules;
BOOST_CHECK(Parse("2010 Apr 02 - May 21: Mo-Su 17:00-24:00", rules));
std::tm time{};
BOOST_CHECK(GetTimeTuple("2010-4-20 18:15", kDateTimeFmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2010-5-20 18:15", kDateTimeFmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2010-4-01 18:15", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2010-5-22 18:15", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2010-6-01 18:15", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
}
{
TRuleSequences rules;
BOOST_CHECK(Parse("Apr-Sep Su 14:30-17:00", rules));
std::tm time{};
BOOST_CHECK(GetTimeTuple("2015-04-12 15:35", kDateTimeFmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-04-13 15:35", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-10-11 15:35", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
}
{
TRuleSequences rules;
BOOST_CHECK(Parse("Mo 09:00-06:00", rules));
std::tm time{};
auto const fmt = "%Y-%m-%d %H:%M";
BOOST_CHECK(GetTimeTuple("2015-11-10 05:35", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-10 05:35", kDateTimeFmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-11-11 05:35", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-11 05:35", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-11-11 06:01", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-11 06:01", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
}
{
@ -1354,14 +1374,13 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TestIsActive)
BOOST_CHECK(Parse("Mo 09:00-32:00", rules));
std::tm time{};
auto const fmt = "%Y-%m-%d %H:%M";
BOOST_CHECK(GetTimeTuple("2015-11-10 05:35", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-10 05:35", kDateTimeFmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-11-11 05:35", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-11 05:35", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-11-11 06:01", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-11 06:01", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
}
{
@ -1369,20 +1388,19 @@ BOOST_AUTO_TEST_CASE(OpeningHours_TestIsActive)
BOOST_CHECK(Parse("Mo 09:00-48:00", rules));
std::tm time{};
auto const fmt = "%Y-%m-%d %H:%M";
BOOST_CHECK(GetTimeTuple("2015-11-10 05:35", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-10 05:35", kDateTimeFmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-11-10 15:35", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-10 15:35", kDateTimeFmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-11-10 23:35", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-10 23:35", kDateTimeFmt, time));
BOOST_CHECK(IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-11-11 05:35", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-11 05:35", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
BOOST_CHECK(GetTimeTuple("2015-11-11 06:01", fmt, time));
BOOST_CHECK(GetTimeTuple("2015-11-11 06:01", kDateTimeFmt, time));
BOOST_CHECK(!IsActive(rules[0], time));
}
}

View file

@ -36,11 +36,12 @@ template<typename Iterator> struct context_parser<osmoh::TRuleSequences, Iterato
using type = osmoh::parsing::time_domain<Iterator>;
};
template <typename Context, typename Iterator>
using context_parser_t = typename context_parser<Context, Iterator>::type;
template <typename Context>
inline bool ParseImp(std::string const & str, Context & context)
bool ParseImp(std::string const & str, Context & context)
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::standard_wide::space;

View file

@ -14,7 +14,7 @@ using osmoh::operator""_h;
constexpr osmoh::MonthDay::TYear kTMYearOrigin = 1900;
inline bool ToHourMinutes(osmoh::Time const & t, THourMinutes & hm)
bool ToHourMinutes(osmoh::Time const & t, THourMinutes & hm)
{
if (!t.IsHoursMinutes())
return false;
@ -22,13 +22,13 @@ inline bool ToHourMinutes(osmoh::Time const & t, THourMinutes & hm)
return true;
}
inline bool ToHourMinutes(std::tm const & t, THourMinutes & hm)
bool ToHourMinutes(std::tm const & t, THourMinutes & hm)
{
hm = THourMinutes{t.tm_hour, t.tm_min};
return true;
}
inline int CompareMonthDayTimeTuple(osmoh::MonthDay const & monthDay, std::tm const & date)
int CompareMonthDayTimeTuple(osmoh::MonthDay const & monthDay, std::tm const & date)
{
if (monthDay.HasYear())
{
@ -51,23 +51,25 @@ inline int CompareMonthDayTimeTuple(osmoh::MonthDay const & monthDay, std::tm co
return 0;
}
inline bool operator<=(osmoh::MonthDay const & monthDay, std::tm const & date)
bool operator<=(osmoh::MonthDay const & monthDay, std::tm const & date)
{
return CompareMonthDayTimeTuple(monthDay, date) < 1;
}
inline bool operator<=(std::tm const & date, osmoh::MonthDay const & monthDay)
bool operator<=(std::tm const & date, osmoh::MonthDay const & monthDay)
{
return CompareMonthDayTimeTuple(monthDay, date) > -1;
}
inline bool operator==(osmoh::MonthDay const & monthDay, std::tm const & date)
bool operator==(osmoh::MonthDay const & monthDay, std::tm const & date)
{
return CompareMonthDayTimeTuple(monthDay, date) == 0;
}
// Fill result with fields that present in start and missing in end.
inline osmoh::MonthDay NormalizeEnd(osmoh::MonthDay const & start, osmoh::MonthDay const & end)
// 2015 Jan 30 - Feb 20 <=> 2015 Jan 30 - 2015 Feb 20
// 2015 Jan 01 - 22 <=> 2015 Jan 01 - 2015 Jan 22
osmoh::MonthDay NormalizeEnd(osmoh::MonthDay const & start, osmoh::MonthDay const & end)
{
osmoh::MonthDay result = start;
if (end.HasYear())
@ -79,7 +81,7 @@ inline osmoh::MonthDay NormalizeEnd(osmoh::MonthDay const & start, osmoh::MonthD
return result;
}
inline uint8_t GetWeekNumber(std::tm const & date)
uint8_t GetWeekNumber(std::tm const & date)
{
char buff[4]{};
if (strftime(&buff[0], sizeof(buff), "%V", &date) == 0)
@ -91,16 +93,16 @@ inline uint8_t GetWeekNumber(std::tm const & date)
return weekNumber;
}
inline bool IsBetweenLooped(osmoh::Weekday const start,
osmoh::Weekday const end,
osmoh::Weekday const p)
bool IsBetweenLooped(osmoh::Weekday const start,
osmoh::Weekday const end,
osmoh::Weekday const p)
{
if (start <= end)
return start <= p && p <= end;
return p >= end || start <= p;
}
inline osmoh::RuleState ModifierToRuleState(osmoh::RuleSequence::Modifier const modifier)
osmoh::RuleState ModifierToRuleState(osmoh::RuleSequence::Modifier const modifier)
{
using Modifier = osmoh::RuleSequence::Modifier;
@ -122,15 +124,15 @@ inline osmoh::RuleState ModifierToRuleState(osmoh::RuleSequence::Modifier const
// Transform timspan with extended end of the form of
// time less than 24 hours to extended form, i.e from 25 to 48 hours.
// Example: 12:15-06:00 -> 12:15-30:00.
inline void NormalizeExtendedEnd(osmoh::Timespan & span)
void NormalizeExtendedEnd(osmoh::Timespan & span)
{
auto & endHouminutes = span.GetEnd().GetHourMinutes();
auto const duration = endHouminutes.GetDuration();
auto & endHourMinutes = span.GetEnd().GetHourMinutes();
auto const duration = endHourMinutes.GetDuration();
if (duration < 24_h)
endHouminutes.SetDuration(duration + 24_h);
endHourMinutes.SetDuration(duration + 24_h);
}
inline osmoh::TTimespans SplitExtendedHours(osmoh::Timespan span)
osmoh::TTimespans SplitExtendedHours(osmoh::Timespan span)
{
osmoh::TTimespans result;
NormalizeExtendedEnd(span);
@ -151,36 +153,35 @@ inline osmoh::TTimespans SplitExtendedHours(osmoh::Timespan span)
return result;
}
inline void SplitExtendedHours(osmoh::TTimespans const & spans,
osmoh::TTimespans & originalNormilizedSpans,
osmoh::Timespan & additionalSpan)
void SplitExtendedHours(osmoh::TTimespans const & spans,
osmoh::TTimespans & originalNormalizedSpans,
osmoh::Timespan & additionalSpan)
{
// We don't handle more than one occurence of extended span
// since it is an invalid situation.
for (auto it = begin(spans); it != end(spans); ++it)
{
if (!it->HasExtendedHours())
{
originalNormilizedSpans.push_back(*it);
continue;
}
auto const splittedSpans = SplitExtendedHours(*it);
originalNormilizedSpans.push_back(splittedSpans[0]);
additionalSpan = splittedSpans[1];
auto it = begin(spans);
for (; it != end(spans) && !it->HasExtendedHours(); ++it)
originalNormalizedSpans.push_back(*it);
++it;
std::copy(it, end(spans), back_inserter(originalNormilizedSpans));
if (it == end(spans))
return;
break;
}
auto const splittedSpans = SplitExtendedHours(*it);
originalNormalizedSpans.push_back(splittedSpans[0]);
additionalSpan = splittedSpans[1];
++it;
std::copy(it, end(spans), back_inserter(originalNormalizedSpans));
}
inline bool HasExtendedHours(osmoh::RuleSequence const & rule)
bool HasExtendedHours(osmoh::RuleSequence const & rule)
{
for (auto const & timespan : rule.GetTimes())
{
if (timespan.HasExtendedHours())
return true;
}
return false;
}
@ -266,8 +267,10 @@ bool IsActive(MonthdayRange const & range, std::tm const & date)
return false;
if (range.HasEnd())
{
return range.GetStart() <= date &&
date <= NormalizeEnd(range.GetStart(), range.GetEnd());
}
return range.GetStart() == date;
}
@ -337,7 +340,10 @@ bool IsActive(RuleSequence const & rule, time_t const timestamp)
if (checkIsActive(rule, dateTimeTMShifted) &&
IsActive(additionalSpan, dateTimeTMShifted))
{
return true;
}
return false;
}