-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
executable file
·131 lines (97 loc) · 2.87 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <boost/range.hpp>
//#include <boost/range/access/front.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <iterator>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/algorithm/string/join.hpp>
#include "range_ext.hpp"
using namespace boost::adaptors;
using namespace boost::range::access;
using namespace boost::range;
const char* monthNames [] = { "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December" };
/// The number of columns per day in the formatted output.
int ColsPerDay = 3;
/// The number of columns per week in the formatted output.
int ColsPerWeek = 7 * ColsPerDay;
std::string spaces(size_t n)
{
return std::string(n, ' ');
}
day_range datesInYear(int year)
{
greg::date year_first_day = greg::date(year, 1, 1);
greg::date next_year_first_day = greg::date(year + 1, 1, 1);
return day_range(year_first_day, next_year_first_day);
}
/**
* Formats the name of a month centered on ColsPerWeek.
*/
std::string monthTitle(int month)
{
// Determine how many spaces before and after the month name we need to
// center it over the formatted weeks in the month
std::string name = monthNames[month - 1];
int before = (ColsPerWeek - name.size()) / 2;
int after = ColsPerWeek - name.size() - before;
return spaces(before) + name + spaces(after);
}
struct formatDay
{
using result_type = std::string;
std::string operator()(const greg::date& d) const
{
std::stringstream ss;
ss << std::setw(2) << d.day().as_number();
return ss.str();
}
};
struct formatWeek
{
using result_type = std::string;
std::string operator()(day_range dates) const
{
std::stringstream ss;
greg::date d = front(dates);
int startDay = d.day_of_week() - 1;
startDay = startDay < 0 ? 6 : startDay;
ss << spaces(ColsPerDay * startDay);
int numDays = 0;
ss << (dates | transformed(formatDay()) | join(" "));
// Insert more filler at the end to fill up the remainder of the
// week, if it's a short week (e.g. at the end of the month).
if (numDays < 7 - startDay)
{
ss << spaces(ColsPerDay * (7 - startDay - numDays));
}
return ss.str();
}
};
struct formatMonth
{
using result_type = std::string;
std::string operator()(day_range monthDay) const
{
std::stringstream ss;
greg::date first_day_of_month = monthDay | boost::range::access::front;
ss << monthTitle(first_day_of_month.month()) << std::endl;
ss << (monthDay | byweek | transformed(formatWeek()) | join("\n"));
ss << std::endl;
return ss.str();
}
};
int main()
{
try
{
auto months = datesInYear(2013)
| bymonth
| transformed(formatMonth());
boost::copy(months, std::ostream_iterator<std::string>(std::cout, "\n"));
}
catch (std::exception& e) {
std::cout << "Error bad date, check your entry: \n"
<< " Details: " << e.what() << std::endl;
}
}