SlideShare a Scribd company logo
Ranges for the Standard Library
C++ Siberia 2015
Eric Niebler
Copyright Eric Niebler 2015
Welcome to This Talk!
• What are ranges good for?
• What parts make up the whole of ranges?
• How do the parts play together?
• Why should you care?
• What has been proposed for standardization?
What will be proposed? When will it land?
The idea for this talk was taken from the article “Component programming
with ranges” on the D language Wiki.
Copyright Eric Niebler 2015
Goal
Copyright Eric Niebler 2015
#include <cstddef>
#include <string>
#include <vector>
#include <utility>
#include <iostream>
#include <stdexcept>
#include <functional>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <range/v3/all.hpp>
namespace greg = boost::gregorian;
using date = greg::date;
using day = greg::date_duration;
using namespace ranges;
using std::cout;
namespace boost { namespace gregorian {
date &operator++(date &d) { return d = d + day(1); }
date operator++(date &d, int) { return ++d - day(1); }
}}
namespace ranges {
template<> struct difference_type<date> {
using type = date::duration_type::duration_rep::int_type;
};
}
CONCEPT_ASSERT(Incrementable<date>());
auto dates_in_year(int year) {
return view::iota(date{year,greg::Jan,1},
date{year+1,greg::Jan,1});
}
auto by_month() {
return view::group_by([](date a, date b) {
return a.month() == b.month();
});
}
auto by_week() {
return view::group_by([](date a, date b) {
// ++a because week_numer is Mon-Sun and we want Sun-Sat
return (++a).week_number() == (++b).week_number();
});
}
std::string format_day(date d) {
return boost::str(boost::format("%|3|") % d.day());
}
// In: Range<Range<date>>: month grouped by weeks.
// Out: Range<std::string>: month with formatted weeks.
auto format_weeks() {
return view::transform([](/*Range<date>*/ auto week) {
return boost::str(boost::format("%1%%2%%|22t|")
% std::string((int)front(week).day_of_week() * 3, ' ')
% (week | view::transform(format_day) | action::join));
});
}
// Return a formatted string with the title of the month
// corresponding to a date.
std::string month_title(date d) {
return boost::str(boost::format("%|=22|")
% d.month().as_long_string());
}
// In: Range<Range<date>>: year of months of days
// Out: Range<Range<std::string>>: year of months of formatted wks
auto layout_months() {
return view::transform([](/*Range<date>*/ auto month) {
int week_count = distance(month | by_week());
return view::concat(
view::single(month_title(front(month))),
month | by_week() | format_weeks(),
view::repeat_n(std::string(22,' '),6-week_count));
});
}
Copyright Eric Niebler 2015
// In: Range<T>
// Out: Range<Range<T>>, where each inner range has $n$ elements.
// The last range may have fewer.
template<class Rng>
class chunk_view : public range_adaptor<chunk_view<Rng>, Rng> {
CONCEPT_ASSERT(ForwardIterable<Rng>());
std::size_t n_;
friend range_access;
class adaptor;
adaptor begin_adaptor() {
return adaptor{n_, ranges::end(this->base())};
}
public:
chunk_view() = default;
chunk_view(Rng rng, std::size_t n)
: range_adaptor_t<chunk_view>(std::move(rng)), n_(n)
{}
};
template<class Rng>
class chunk_view<Rng>::adaptor : public adaptor_base {
std::size_t n_;
range_sentinel_t<Rng> end_;
using adaptor_base::prev;
public:
adaptor() = default;
adaptor(std::size_t n, range_sentinel_t<Rng> end)
: n_(n), end_(end)
{}
auto current(range_iterator_t<Rng> it) const {
return view::take(make_range(std::move(it), end_), n_);
}
void next(range_iterator_t<Rng> &it) {
ranges::advance(it, n_, end_);
}
};
// In: Range<T>
// Out: Range<Range<T>>, where each inner range has $n$ elements.
// The last range may have fewer.
auto chunk(std::size_t n) {
return make_pipeable([=](auto&& rng) {
using Rng = decltype(rng);
return chunk_view<view::all_t<Rng>>{
view::all(std::forward<Rng>(rng)), n};
});
}
// Flattens a range of ranges by iterating the inner
// ranges in round-robin fashion.
template<class Rngs>
class interleave_view : public range_facade<interleave_view<Rngs>> {
friend range_access;
std::vector<range_value_t<Rngs>> rngs_;
struct cursor;
cursor begin_cursor() {
return {0, &rngs_, view::transform(rngs_, ranges::begin)};
}
public:
interleave_view() = default;
explicit interleave_view(Rngs rngs)
: rngs_(std::move(rngs))
{}
};
template<class Rngs>
struct interleave_view<Rngs>::cursor {
std::size_t n_;
std::vector<range_value_t<Rngs>> *rngs_;
std::vector<range_iterator_t<range_value_t<Rngs>>> its_;
decltype(auto) current() const {
return *its_[n_];
}
void next() {
if(0 == ((++n_) %= its_.size()))
for_each(its_, [](auto& it){ ++it; });
}
bool done() const {
return n_ == 0 && its_.end() != mismatch(its_,
view::transform(*rngs_, ranges::end),
std::not_equal_to<>()).first;
}
CONCEPT_REQUIRES(ForwardIterable<range_value_t<Rngs>>())
bool equal(cursor const& that) const {
return n_ == that.n_ && its_ == that.its_;
}
};
// In: Range<Range<T>>
// Out: Range<T>, flattened by walking the ranges
// round-robin fashion.
auto interleave() {
return make_pipeable([](auto&& rngs) {
using Rngs = decltype(rngs);
return interleave_view<view::all_t<Rngs>>(
view::all(std::forward<Rngs>(rngs)));
});
}
// In: Range<Range<T>>
// Out: Range<Range<T>>, transposing the rows and columns.
auto transpose() {
return make_pipeable([](auto&& rngs) {
using Rngs = decltype(rngs);
CONCEPT_ASSERT(ForwardIterable<Rngs>());
return std::forward<Rngs>(rngs)
| interleave()
| chunk(distance(rngs));
});
}
// In: Range<Range<Range<string>>>
// Out: Range<Range<Range<string>>>, transposing months.
auto transpose_months() {
return view::transform([](/*Range<Range<string>>*/ auto rng) {
return rng | transpose();
});
}
// In: Range<Range<string>>
// Out: Range<string>, joining the strings of the inner ranges
auto join_months() {
return view::transform([](/*Range<string>*/ auto rng) {
return action::join(rng);
});
}
int main(int argc, char *argv[]) try {
if(argc < 2) {
std::cerr << "Please enter the year to format.n";
std::cerr << boost::format(" Usage: %1% <year>n") % argv[0];
return 1;
}
int year = boost::lexical_cast<int>(argv[1]);
int months_per_line = 3;
auto calendar =
// Make a range of all the dates in a year:
dates_in_year(year)
// Group the dates by month:
| by_month()
// Format the month into a range of strings:
| layout_months()
// Group the months that belong side-by-side:
| chunk(months_per_line)
// Transpose the rows and columns of the size-by-side months:
| transpose_months()
// Ungroup the side-by-side months:
| view::join
// Join the strings of the transposed months:
| join_months();
// Write the result to stdout:
copy(calendar, ostream_iterator<>(std::cout, "n"));
}
catch(std::exception &e) {
std::cerr << "ERROR: Unhandled exceptionn";
std::cerr << " what(): " << e.what();
return 1;
}
Step 1
Create a range of dates.
Copyright Eric Niebler 2015
Hello, Date_time!
Copyright Eric Niebler 2015
Hello, Range!
Copyright Eric Niebler 2015
Range-v3: https://github.com/ericniebler/range-v3
Range Views
• Begin/end members return iterator/sentinel
• Lazy sequence algorithms
• Lightweight, non-owning
• Composable
• Non-mutating
Copyright Eric Niebler 2015
Range of dates = 
Copyright Eric Niebler 2015
Range of dates = 
Copyright Eric Niebler 2015
Range of dates = HACKHACK
Copyright Eric Niebler 2015
Range of dates = HACKHACK
Copyright Eric Niebler 2015
Step 2
Group the range of dates into months.
Copyright Eric Niebler 2015
Group Dates into Months
Copyright Eric Niebler 2015
Group Dates into Months
Copyright Eric Niebler 2015
Refactor for Readability
Copyright Eric Niebler 2015
Move the group_by
expression into its
own named adaptor.
Built-in Range Views
adjacent_remove_if drop_while map split
all empty move stride
any_range filter partial_sum tail
bounded for_each remove_if take
c_str generate repeat take_exactly
chunk generate_n repeat_n take_while
concat group_by replace tokenize
const_ indirect replace_if transform
counted intersperse reverse unbounded
delimit iota single unique
drop join slice zip[_with]
Copyright Eric Niebler 2015
Step 3
Group months into weeks.
Copyright Eric Niebler 2015
Group Months into Weeks
Copyright Eric Niebler 2015
Group Months into Weeks
Copyright Eric Niebler 2015
Step 4
Format the weeks
Copyright Eric Niebler 2015
Format the Weeks
Copyright Eric Niebler 2015
Range Actions
• Eager sequence algorithms
• Can operate on and return containers
• Composable
• Potentially mutating
Copyright Eric Niebler 2015
Views vs. Actions
Range Views Range Actions
Lazy sequence algorithms Eager sequence algorithms
Lightweight, non-owning Can operate on and return
containers
Composable Composable
Non-mutating Potentially mutating
Copyright Eric Niebler 2015
Built-in Range Action
drop push_front stable_sort
drop_while remove_if stride
erase shuffle take
insert slice take_while
join sort transform
push_back split unique
Copyright Eric Niebler 2015
So Far, So Good
Copyright Eric Niebler 2015
Step 5
Copyright Eric Niebler 2015
Add month title and padded weeks.
Month Title
Copyright Eric Niebler 2015
view::concat lazily
concatenates ranges.
view::single creates
a 1-element range.
Month Title
Copyright Eric Niebler 2015
Padding Short Months
Copyright Eric Niebler 2015
A formatted month takes as few as four and as
many as six lines.
For side-by-side display of months, they must all
occupy the same vertical space.
Pad the short months with empty lines.
Padding Short Months
Copyright Eric Niebler 2015
view::repeat_n creates
an N-element range.
Padding Short Months
Copyright Eric Niebler 2015
So Far, So Good
Copyright Eric Niebler 2015
A “year” is a range of “months”.
A “month” is a range of strings.
Each “month” has exactly 7 lines.
by_month() and layout_months()
are reusable, and work even if the
input range of dates is infinite!
Side-by-Side Month Layout
Copyright Eric Niebler 2015
Side-by-Side Month Layout
Copyright Eric Niebler 2015
J
F
M
A
M
J
J
A
S
O
N
D
J F M
A M J
J A S
Side-by-Side Month Layout
1. Chunk months into groups of 3’s.
2. For each group of 3 months, transpose
the “rows” and “columns”.
3. Join the chunks created in step 1.
4. Join the strings of the inner ranges.
5. Print!
6. Take the rest of the day off.
Copyright Eric Niebler 2015
Chunking: Custom Range Adaptor
Copyright Eric Niebler 2015
Chunking: Custom Range Adaptor
Copyright Eric Niebler 2015
Chunking: Custom Range Adaptor
Copyright Eric Niebler 2015
Chunking: Custom Range Adaptor
Copyright Eric Niebler 2015
make_pipeable
• “chunk” takes two arguments:
– The range to chunk
– The size of the chunks
• “rng | chunk(n)”
Copyright Eric Niebler 2015
Must return an object that
has overloaded operator|
make_pipeable
Copyright Eric Niebler 2015
A function of 1 argument
Forwards the arg to the function
Chunking: Custom Range Adaptor
Copyright Eric Niebler 2015
Chunking: Custom Range Adaptor
Copyright Eric Niebler 2015
Transpose Range of Ranges
Copyright Eric Niebler 2015
Transpose Range of Ranges
January Jan Wk 1 Jan Wk 2 Jan Wk 3 Jan Wk 4 Jan Wk 5 Jan Wk 6
February Feb Wk 1 Feb Wk 2 Feb Wk 3 Feb Wk 4 Feb Wk 5 Feb Wk 6
March Mar Wk 1 Mar Wk 2 Mar Wk 3 Mar Wk 4 Mar Wk 5 Mar Wk 6
Copyright Eric Niebler 2015
January
February
March
Jan Wk 1
Feb Wk 1
Mar Wk 1
Jan Wk 2
…
January February March
Jan Wk 1 Feb Wk 1 Mar Wk 1
Jan Wk 2 Feb Wk 2 Mar Wk 2
Jan Wk 3 Feb Wk 3 Mar Wk 3
Jan Wk 4 Feb Wk 4 Mar Wk 4
Jan Wk 5 Feb Wk 5 Mar Wk 5
Jan Wk 6 Feb Wk 6 Mar Wk 6
1. Interleave
2. Chunk
Interleave: Custom Range Facade
Copyright Eric Niebler 2015
Interleave: Custom Range Facade
Copyright Eric Niebler 2015
Interleave: Custom Range Facade
Copyright Eric Niebler 2015
Interleave: Custom Range Facade
Copyright Eric Niebler 2015
Interleave: Custom Range Facade
Copyright Eric Niebler 2015
Transpose Range of Ranges
Copyright Eric Niebler 2015
Side-by-Side Month Layout
1. Chunk months into groups of 3’s.
2. For each group of 3 months, transpose the
“rows” and “columns”.
3. Join the chunks created in step 1
4. Join the strings of the inner ranges.
5. Print!
6. Take the rest of the day off.
Copyright Eric Niebler 2015
Solution
Copyright Eric Niebler 2015
Solution
Copyright Eric Niebler 2015
Ta-da!
Copyright Eric Niebler 2015
Calendar Solution
Copyright Eric Niebler 2015
Works with
infinite ranges
Composable
Reusable
Can show N months
side-by-side
No loops!!!
Correct by
construction.
#include <cstddef>
#include <string>
#include <vector>
#include <utility>
#include <iostream>
#include <stdexcept>
#include <functional>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <range/v3/all.hpp>
namespace greg = boost::gregorian;
using date = greg::date;
using day = greg::date_duration;
using namespace ranges;
using std::cout;
namespace boost { namespace gregorian {
date &operator++(date &d) { return d = d + day(1); }
date operator++(date &d, int) { return ++d - day(1); }
}}
namespace ranges {
template<> struct difference_type<date> {
using type = date::duration_type::duration_rep::int_type;
};
}
CONCEPT_ASSERT(Incrementable<date>());
auto dates_in_year(int year) {
return view::iota(date{year,greg::Jan,1},
date{year+1,greg::Jan,1});
}
auto by_month() {
return view::group_by([](date a, date b) {
return a.month() == b.month();
});
}
auto by_week() {
return view::group_by([](date a, date b) {
// ++a because week_numer is Mon-Sun and we want Sun-Sat
return (++a).week_number() == (++b).week_number();
});
}
std::string format_day(date d) {
return boost::str(boost::format("%|3|") % d.day());
}
// In: Range<Range<date>>: month grouped by weeks.
// Out: Range<std::string>: month with formatted weeks.
auto format_weeks() {
return view::transform([](/*Range<date>*/ auto week) {
return boost::str(boost::format("%1%%2%%|22t|")
% std::string((int)front(week).day_of_week() * 3, ' ')
% (week | view::transform(format_day) | action::join));
});
}
// Return a formatted string with the title of the month
// corresponding to a date.
std::string month_title(date d) {
return boost::str(boost::format("%|=22|")
% d.month().as_long_string());
}
// In: Range<Range<date>>: year of months of days
// Out: Range<Range<std::string>>: year of months of formatted wks
auto layout_months() {
return view::transform([](/*Range<date>*/ auto month) {
int week_count = distance(month | by_week());
return view::concat(
view::single(month_title(front(month))),
month | by_week() | format_weeks(),
view::repeat_n(std::string(22,' '),6-week_count));
});
}
Copyright Eric Niebler 2015
// In: Range<T>
// Out: Range<Range<T>>, where each inner range has $n$ elements.
// The last range may have fewer.
template<class Rng>
class chunk_view : public range_adaptor<chunk_view<Rng>, Rng> {
CONCEPT_ASSERT(ForwardIterable<Rng>());
std::size_t n_;
friend range_access;
class adaptor;
adaptor begin_adaptor() {
return adaptor{n_, ranges::end(this->base())};
}
public:
chunk_view() = default;
chunk_view(Rng rng, std::size_t n)
: range_adaptor_t<chunk_view>(std::move(rng)), n_(n)
{}
};
template<class Rng>
class chunk_view<Rng>::adaptor : public adaptor_base {
std::size_t n_;
range_sentinel_t<Rng> end_;
using adaptor_base::prev;
public:
adaptor() = default;
adaptor(std::size_t n, range_sentinel_t<Rng> end)
: n_(n), end_(end)
{}
auto current(range_iterator_t<Rng> it) const {
return view::take(make_range(std::move(it), end_), n_);
}
void next(range_iterator_t<Rng> &it) {
ranges::advance(it, n_, end_);
}
};
// In: Range<T>
// Out: Range<Range<T>>, where each inner range has $n$ elements.
// The last range may have fewer.
auto chunk(std::size_t n) {
return make_pipeable([=](auto&& rng) {
using Rng = decltype(rng);
return chunk_view<view::all_t<Rng>>{
view::all(std::forward<Rng>(rng)), n};
});
}
// Flattens a range of ranges by iterating the inner
// ranges in round-robin fashion.
template<class Rngs>
class interleave_view : public range_facade<interleave_view<Rngs>> {
friend range_access;
std::vector<range_value_t<Rngs>> rngs_;
struct cursor;
cursor begin_cursor() {
return {0, &rngs_, view::transform(rngs_, ranges::begin)};
}
public:
interleave_view() = default;
explicit interleave_view(Rngs rngs)
: rngs_(std::move(rngs))
{}
};
template<class Rngs>
struct interleave_view<Rngs>::cursor {
std::size_t n_;
std::vector<range_value_t<Rngs>> *rngs_;
std::vector<range_iterator_t<range_value_t<Rngs>>> its_;
decltype(auto) current() const {
return *its_[n_];
}
void next() {
if(0 == ((++n_) %= its_.size()))
for_each(its_, [](auto& it){ ++it; });
}
bool done() const {
return n_ == 0 && its_.end() != mismatch(its_,
view::transform(*rngs_, ranges::end),
std::not_equal_to<>()).first;
}
CONCEPT_REQUIRES(ForwardIterable<range_value_t<Rngs>>())
bool equal(cursor const& that) const {
return n_ == that.n_ && its_ == that.its_;
}
};
// In: Range<Range<T>>
// Out: Range<T>, flattened by walking the ranges
// round-robin fashion.
auto interleave() {
return make_pipeable([](auto&& rngs) {
using Rngs = decltype(rngs);
return interleave_view<view::all_t<Rngs>>(
view::all(std::forward<Rngs>(rngs)));
});
}
// In: Range<Range<T>>
// Out: Range<Range<T>>, transposing the rows and columns.
auto transpose() {
return make_pipeable([](auto&& rngs) {
using Rngs = decltype(rngs);
CONCEPT_ASSERT(ForwardIterable<Rngs>());
return std::forward<Rngs>(rngs)
| interleave()
| chunk(distance(rngs));
});
}
// In: Range<Range<Range<string>>>
// Out: Range<Range<Range<string>>>, transposing months.
auto transpose_months() {
return view::transform([](/*Range<Range<string>>*/ auto rng) {
return rng | transpose();
});
}
// In: Range<Range<string>>
// Out: Range<string>, joining the strings of the inner ranges
auto join_months() {
return view::transform([](/*Range<string>*/ auto rng) {
return action::join(rng);
});
}
int main(int argc, char *argv[]) try {
if(argc < 2) {
std::cerr << "Please enter the year to format.n";
std::cerr << boost::format(" Usage: %1% <year>n") % argv[0];
return 1;
}
int year = boost::lexical_cast<int>(argv[1]);
int months_per_line = 3;
auto calendar =
// Make a range of all the dates in a year:
dates_in_year(year)
// Group the dates by month:
| by_month()
// Format the month into a range of strings:
| layout_months()
// Group the months that belong side-by-side:
| chunk(months_per_line)
// Transpose the rows and columns of the size-by-side months:
| transpose_months()
// Ungroup the side-by-side months:
| view::join
// Join the strings of the transposed months:
| join_months();
// Write the result to stdout:
copy(calendar, ostream_iterator<>(std::cout, "n"));
}
catch(std::exception &e) {
std::cerr << "ERROR: Unhandled exceptionn";
std::cerr << " what(): " << e.what();
return 1;
}
Ranges and Standardization
Copyright Eric Niebler 2015
Feature Already
Proposed?
Will be
Proposed?
Range concepts
Range algorithms
View adaptors
Range actions
Façade/Adaptor
helpers
Copyright Eric Niebler 2015
Initial proposal of the design.2014 Oct
Cursory review of concepts and algorithms.2015 May
Detailed wording review of concepts and algorithms.
Draft other range-related proposals[1].
Present
Vote initial wording into a draft TS.
Review wording of other proposals.
2015 Oct (??)
[1] proxy iterators TS is approved.???
TS is merged into C++XY as STL2.???
Standardization Timeline
Even more range-related proposals[2].Next year(s)
[2] Infinite ranges, range
views and actions, façade,
adaptor.
Find Out More
• N4128
• High-level design, rationale, comparative analysis
• http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2014/n4128.html
• N4382
• Standard wording for concepts, iterators, algorithms
• http://www.open-
std.org/JTC1/SC22/WG21/docs/papers/2015/n4382.pdf
• Range v3 library
• C++11 implementation
• http://www.github.com/ericniebler/range-v3
Copyright Eric Niebler 2015
Questions?
Copyright Eric Niebler 2015

More Related Content

What's hot

C++11 smart pointer
C++11 smart pointerC++11 smart pointer
C++11 smart pointerLei Yu
 
The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210
Mahmoud Samir Fayed
 
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Abu Saleh
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzer
Andrey Karpov
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
Andrey Karpov
 
Java Practical File Diploma
Java Practical File DiplomaJava Practical File Diploma
Java Practical File Diploma
mustkeem khan
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: FunctionsAdam Crabtree
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
David de Boer
 
DSU C&C++ Practical File Diploma
DSU C&C++ Practical File DiplomaDSU C&C++ Practical File Diploma
DSU C&C++ Practical File Diploma
mustkeem khan
 
Extend GraphQL with directives
Extend GraphQL with directivesExtend GraphQL with directives
Extend GraphQL with directives
Greg Bergé
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
Colin DeCarlo
 
Java script
Java scriptJava script
Java script
Dhananjay Kumar
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
ssuserd6b1fd
 
The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181
Mahmoud Samir Fayed
 
Swift で JavaScript 始めませんか? #iOSDC
Swift で JavaScript 始めませんか? #iOSDCSwift で JavaScript 始めませんか? #iOSDC
Swift で JavaScript 始めませんか? #iOSDC
Tomohiro Kumagai
 
Ds lab manual by s.k.rath
Ds lab manual by s.k.rathDs lab manual by s.k.rath
Ds lab manual by s.k.rathSANTOSH RATH
 
科特林λ學
科特林λ學科特林λ學
科特林λ學
彥彬 洪
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
Brian Moschel
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
Sumant Tambe
 
Lab manual data structure (cs305 rgpv) (usefulsearch.org) (useful search)
Lab manual data structure (cs305 rgpv) (usefulsearch.org)  (useful search)Lab manual data structure (cs305 rgpv) (usefulsearch.org)  (useful search)
Lab manual data structure (cs305 rgpv) (usefulsearch.org) (useful search)
Make Mannan
 

What's hot (20)

C++11 smart pointer
C++11 smart pointerC++11 smart pointer
C++11 smart pointer
 
The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210The Ring programming language version 1.9 book - Part 94 of 210
The Ring programming language version 1.9 book - Part 94 of 210
 
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13Lecture 3, c++(complete reference,herbet sheidt)chapter-13
Lecture 3, c++(complete reference,herbet sheidt)chapter-13
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzer
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
Java Practical File Diploma
Java Practical File DiplomaJava Practical File Diploma
Java Practical File Diploma
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: Functions
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
DSU C&C++ Practical File Diploma
DSU C&C++ Practical File DiplomaDSU C&C++ Practical File Diploma
DSU C&C++ Practical File Diploma
 
Extend GraphQL with directives
Extend GraphQL with directivesExtend GraphQL with directives
Extend GraphQL with directives
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 
Java script
Java scriptJava script
Java script
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
 
The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181
 
Swift で JavaScript 始めませんか? #iOSDC
Swift で JavaScript 始めませんか? #iOSDCSwift で JavaScript 始めませんか? #iOSDC
Swift で JavaScript 始めませんか? #iOSDC
 
Ds lab manual by s.k.rath
Ds lab manual by s.k.rathDs lab manual by s.k.rath
Ds lab manual by s.k.rath
 
科特林λ學
科特林λ學科特林λ學
科特林λ學
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
 
Lab manual data structure (cs305 rgpv) (usefulsearch.org) (useful search)
Lab manual data structure (cs305 rgpv) (usefulsearch.org)  (useful search)Lab manual data structure (cs305 rgpv) (usefulsearch.org)  (useful search)
Lab manual data structure (cs305 rgpv) (usefulsearch.org) (useful search)
 

Viewers also liked

HPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычисленийHPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычислений
Platonov Sergey
 
Визуализация автомобильных маршрутов
Визуализация автомобильных маршрутовВизуализация автомобильных маршрутов
Визуализация автомобильных маршрутов
Platonov Sergey
 
Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++
Platonov Sergey
 
One definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим житьOne definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим жить
Platonov Sergey
 
Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...
Platonov Sergey
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Platonov Sergey
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансы
Platonov Sergey
 
Concepts lite
Concepts liteConcepts lite
Concepts lite
Platonov Sergey
 
QML\Qt Quick на практике
QML\Qt Quick на практикеQML\Qt Quick на практике
QML\Qt Quick на практике
Platonov Sergey
 
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Platonov Sergey
 
C++ exceptions
C++ exceptionsC++ exceptions
C++ exceptions
Platonov Sergey
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IIДмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Platonov Sergey
 
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на LinuxПавел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Platonov Sergey
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.
Platonov Sergey
 
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеТененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Platonov Sergey
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Platonov Sergey
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
Sergey Platonov
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
Sergey Platonov
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
victor-yastrebov
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Platonov Sergey
 

Viewers also liked (20)

HPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычисленийHPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычислений
 
Визуализация автомобильных маршрутов
Визуализация автомобильных маршрутовВизуализация автомобильных маршрутов
Визуализация автомобильных маршрутов
 
Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++
 
One definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим житьOne definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим жить
 
Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансы
 
Concepts lite
Concepts liteConcepts lite
Concepts lite
 
QML\Qt Quick на практике
QML\Qt Quick на практикеQML\Qt Quick на практике
QML\Qt Quick на практике
 
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
 
C++ exceptions
C++ exceptionsC++ exceptions
C++ exceptions
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IIДмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
 
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на LinuxПавел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.
 
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеТененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 

Similar to Ranges calendar-novosibirsk-2015-08

Introduction to C ++.pptx
Introduction to C ++.pptxIntroduction to C ++.pptx
Introduction to C ++.pptx
VAIBHAVKADAGANCHI
 
FluentMigrator - Dayton .NET - July 2023
FluentMigrator - Dayton .NET - July 2023FluentMigrator - Dayton .NET - July 2023
FluentMigrator - Dayton .NET - July 2023
Matthew Groves
 
1To ADD name, titleFrom ADD your nameDate ADD date Subject S.docx
1To ADD name, titleFrom ADD your nameDate ADD date Subject S.docx1To ADD name, titleFrom ADD your nameDate ADD date Subject S.docx
1To ADD name, titleFrom ADD your nameDate ADD date Subject S.docx
lorainedeserre
 
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Igalia
 
What’s new in .NET
What’s new in .NETWhat’s new in .NET
What’s new in .NET
Doommaker
 
C
CC
OOP.pptx
OOP.pptxOOP.pptx
OOP.pptx
saifnasir3
 
Java Lab Manual
Java Lab ManualJava Lab Manual
Java Lab Manual
Naveen Sagayaselvaraj
 
Developing a Culture of Quality Code (Midwest PHP 2020)
Developing a Culture of Quality Code (Midwest PHP 2020)Developing a Culture of Quality Code (Midwest PHP 2020)
Developing a Culture of Quality Code (Midwest PHP 2020)
Scott Keck-Warren
 
C++.pptx
C++.pptxC++.pptx
C++.pptx
Sabi995708
 
High ROI Testing in Angular.pptx
High ROI Testing in Angular.pptxHigh ROI Testing in Angular.pptx
High ROI Testing in Angular.pptx
Christian Lüdemann
 
Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...
Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...
Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...
Codemotion
 
Build Your Own Angular Component Library
Build Your Own Angular Component LibraryBuild Your Own Angular Component Library
Build Your Own Angular Component Library
Carlo Bonamico
 
Prog1-L2.pptx
Prog1-L2.pptxProg1-L2.pptx
Prog1-L2.pptx
valerie5142000
 
Reactive programming with RxJS - Taiwan
Reactive programming with RxJS - TaiwanReactive programming with RxJS - Taiwan
Reactive programming with RxJS - Taiwan
modernweb
 
Refactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerRefactoring Tips by Martin Fowler
Refactoring Tips by Martin Fowler
Igor Crvenov
 
Dafunctor
DafunctorDafunctor
Dafunctor
Buganini Chiu
 
ASP.Net 5 and C# 6
ASP.Net 5 and C# 6ASP.Net 5 and C# 6
ASP.Net 5 and C# 6
Andy Butland
 

Similar to Ranges calendar-novosibirsk-2015-08 (20)

Introduction to C ++.pptx
Introduction to C ++.pptxIntroduction to C ++.pptx
Introduction to C ++.pptx
 
FluentMigrator - Dayton .NET - July 2023
FluentMigrator - Dayton .NET - July 2023FluentMigrator - Dayton .NET - July 2023
FluentMigrator - Dayton .NET - July 2023
 
1To ADD name, titleFrom ADD your nameDate ADD date Subject S.docx
1To ADD name, titleFrom ADD your nameDate ADD date Subject S.docx1To ADD name, titleFrom ADD your nameDate ADD date Subject S.docx
1To ADD name, titleFrom ADD your nameDate ADD date Subject S.docx
 
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
Standardizing JavaScript Decorators in TC39 (Full Stack Fest 2019)
 
What’s new in .NET
What’s new in .NETWhat’s new in .NET
What’s new in .NET
 
Intro to Rails 4
Intro to Rails 4Intro to Rails 4
Intro to Rails 4
 
C
CC
C
 
OOP.pptx
OOP.pptxOOP.pptx
OOP.pptx
 
Java Lab Manual
Java Lab ManualJava Lab Manual
Java Lab Manual
 
Developing a Culture of Quality Code (Midwest PHP 2020)
Developing a Culture of Quality Code (Midwest PHP 2020)Developing a Culture of Quality Code (Midwest PHP 2020)
Developing a Culture of Quality Code (Midwest PHP 2020)
 
C++.pptx
C++.pptxC++.pptx
C++.pptx
 
JavaProgrammingManual
JavaProgrammingManualJavaProgrammingManual
JavaProgrammingManual
 
High ROI Testing in Angular.pptx
High ROI Testing in Angular.pptxHigh ROI Testing in Angular.pptx
High ROI Testing in Angular.pptx
 
Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...
Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...
Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...
 
Build Your Own Angular Component Library
Build Your Own Angular Component LibraryBuild Your Own Angular Component Library
Build Your Own Angular Component Library
 
Prog1-L2.pptx
Prog1-L2.pptxProg1-L2.pptx
Prog1-L2.pptx
 
Reactive programming with RxJS - Taiwan
Reactive programming with RxJS - TaiwanReactive programming with RxJS - Taiwan
Reactive programming with RxJS - Taiwan
 
Refactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerRefactoring Tips by Martin Fowler
Refactoring Tips by Martin Fowler
 
Dafunctor
DafunctorDafunctor
Dafunctor
 
ASP.Net 5 and C# 6
ASP.Net 5 and C# 6ASP.Net 5 and C# 6
ASP.Net 5 and C# 6
 

More from Platonov Sergey

Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Platonov Sergey
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
Platonov Sergey
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузера
Platonov Sergey
 
Денис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система QtДенис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система Qt
Platonov Sergey
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free maps
Platonov Sergey
 
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Platonov Sergey
 
High quality library from scratch
High quality library from scratchHigh quality library from scratch
High quality library from scratch
Platonov Sergey
 
С++ without new and delete
С++ without new and deleteС++ without new and delete
С++ without new and delete
Platonov Sergey
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ ProgrammerPlatonov Sergey
 
Библиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLLБиблиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLL
Platonov Sergey
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesPlatonov Sergey
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
Platonov Sergey
 
С++ without new and delete
С++ without new and deleteС++ without new and delete
С++ without new and delete
Platonov Sergey
 

More from Platonov Sergey (13)

Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузера
 
Денис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система QtДенис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система Qt
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free maps
 
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
 
High quality library from scratch
High quality library from scratchHigh quality library from scratch
High quality library from scratch
 
С++ without new and delete
С++ without new and deleteС++ without new and delete
С++ without new and delete
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ Programmer
 
Библиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLLБиблиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLL
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
 
С++ without new and delete
С++ without new and deleteС++ without new and delete
С++ without new and delete
 

Recently uploaded

GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 

Recently uploaded (20)

GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 

Ranges calendar-novosibirsk-2015-08

  • 1. Ranges for the Standard Library C++ Siberia 2015 Eric Niebler Copyright Eric Niebler 2015
  • 2. Welcome to This Talk! • What are ranges good for? • What parts make up the whole of ranges? • How do the parts play together? • Why should you care? • What has been proposed for standardization? What will be proposed? When will it land? The idea for this talk was taken from the article “Component programming with ranges” on the D language Wiki. Copyright Eric Niebler 2015
  • 4. #include <cstddef> #include <string> #include <vector> #include <utility> #include <iostream> #include <stdexcept> #include <functional> #include <boost/format.hpp> #include <boost/lexical_cast.hpp> #include <boost/date_time/gregorian/gregorian.hpp> #include <range/v3/all.hpp> namespace greg = boost::gregorian; using date = greg::date; using day = greg::date_duration; using namespace ranges; using std::cout; namespace boost { namespace gregorian { date &operator++(date &d) { return d = d + day(1); } date operator++(date &d, int) { return ++d - day(1); } }} namespace ranges { template<> struct difference_type<date> { using type = date::duration_type::duration_rep::int_type; }; } CONCEPT_ASSERT(Incrementable<date>()); auto dates_in_year(int year) { return view::iota(date{year,greg::Jan,1}, date{year+1,greg::Jan,1}); } auto by_month() { return view::group_by([](date a, date b) { return a.month() == b.month(); }); } auto by_week() { return view::group_by([](date a, date b) { // ++a because week_numer is Mon-Sun and we want Sun-Sat return (++a).week_number() == (++b).week_number(); }); } std::string format_day(date d) { return boost::str(boost::format("%|3|") % d.day()); } // In: Range<Range<date>>: month grouped by weeks. // Out: Range<std::string>: month with formatted weeks. auto format_weeks() { return view::transform([](/*Range<date>*/ auto week) { return boost::str(boost::format("%1%%2%%|22t|") % std::string((int)front(week).day_of_week() * 3, ' ') % (week | view::transform(format_day) | action::join)); }); } // Return a formatted string with the title of the month // corresponding to a date. std::string month_title(date d) { return boost::str(boost::format("%|=22|") % d.month().as_long_string()); } // In: Range<Range<date>>: year of months of days // Out: Range<Range<std::string>>: year of months of formatted wks auto layout_months() { return view::transform([](/*Range<date>*/ auto month) { int week_count = distance(month | by_week()); return view::concat( view::single(month_title(front(month))), month | by_week() | format_weeks(), view::repeat_n(std::string(22,' '),6-week_count)); }); } Copyright Eric Niebler 2015 // In: Range<T> // Out: Range<Range<T>>, where each inner range has $n$ elements. // The last range may have fewer. template<class Rng> class chunk_view : public range_adaptor<chunk_view<Rng>, Rng> { CONCEPT_ASSERT(ForwardIterable<Rng>()); std::size_t n_; friend range_access; class adaptor; adaptor begin_adaptor() { return adaptor{n_, ranges::end(this->base())}; } public: chunk_view() = default; chunk_view(Rng rng, std::size_t n) : range_adaptor_t<chunk_view>(std::move(rng)), n_(n) {} }; template<class Rng> class chunk_view<Rng>::adaptor : public adaptor_base { std::size_t n_; range_sentinel_t<Rng> end_; using adaptor_base::prev; public: adaptor() = default; adaptor(std::size_t n, range_sentinel_t<Rng> end) : n_(n), end_(end) {} auto current(range_iterator_t<Rng> it) const { return view::take(make_range(std::move(it), end_), n_); } void next(range_iterator_t<Rng> &it) { ranges::advance(it, n_, end_); } }; // In: Range<T> // Out: Range<Range<T>>, where each inner range has $n$ elements. // The last range may have fewer. auto chunk(std::size_t n) { return make_pipeable([=](auto&& rng) { using Rng = decltype(rng); return chunk_view<view::all_t<Rng>>{ view::all(std::forward<Rng>(rng)), n}; }); } // Flattens a range of ranges by iterating the inner // ranges in round-robin fashion. template<class Rngs> class interleave_view : public range_facade<interleave_view<Rngs>> { friend range_access; std::vector<range_value_t<Rngs>> rngs_; struct cursor; cursor begin_cursor() { return {0, &rngs_, view::transform(rngs_, ranges::begin)}; } public: interleave_view() = default; explicit interleave_view(Rngs rngs) : rngs_(std::move(rngs)) {} }; template<class Rngs> struct interleave_view<Rngs>::cursor { std::size_t n_; std::vector<range_value_t<Rngs>> *rngs_; std::vector<range_iterator_t<range_value_t<Rngs>>> its_; decltype(auto) current() const { return *its_[n_]; } void next() { if(0 == ((++n_) %= its_.size())) for_each(its_, [](auto& it){ ++it; }); } bool done() const { return n_ == 0 && its_.end() != mismatch(its_, view::transform(*rngs_, ranges::end), std::not_equal_to<>()).first; } CONCEPT_REQUIRES(ForwardIterable<range_value_t<Rngs>>()) bool equal(cursor const& that) const { return n_ == that.n_ && its_ == that.its_; } }; // In: Range<Range<T>> // Out: Range<T>, flattened by walking the ranges // round-robin fashion. auto interleave() { return make_pipeable([](auto&& rngs) { using Rngs = decltype(rngs); return interleave_view<view::all_t<Rngs>>( view::all(std::forward<Rngs>(rngs))); }); } // In: Range<Range<T>> // Out: Range<Range<T>>, transposing the rows and columns. auto transpose() { return make_pipeable([](auto&& rngs) { using Rngs = decltype(rngs); CONCEPT_ASSERT(ForwardIterable<Rngs>()); return std::forward<Rngs>(rngs) | interleave() | chunk(distance(rngs)); }); } // In: Range<Range<Range<string>>> // Out: Range<Range<Range<string>>>, transposing months. auto transpose_months() { return view::transform([](/*Range<Range<string>>*/ auto rng) { return rng | transpose(); }); } // In: Range<Range<string>> // Out: Range<string>, joining the strings of the inner ranges auto join_months() { return view::transform([](/*Range<string>*/ auto rng) { return action::join(rng); }); } int main(int argc, char *argv[]) try { if(argc < 2) { std::cerr << "Please enter the year to format.n"; std::cerr << boost::format(" Usage: %1% <year>n") % argv[0]; return 1; } int year = boost::lexical_cast<int>(argv[1]); int months_per_line = 3; auto calendar = // Make a range of all the dates in a year: dates_in_year(year) // Group the dates by month: | by_month() // Format the month into a range of strings: | layout_months() // Group the months that belong side-by-side: | chunk(months_per_line) // Transpose the rows and columns of the size-by-side months: | transpose_months() // Ungroup the side-by-side months: | view::join // Join the strings of the transposed months: | join_months(); // Write the result to stdout: copy(calendar, ostream_iterator<>(std::cout, "n")); } catch(std::exception &e) { std::cerr << "ERROR: Unhandled exceptionn"; std::cerr << " what(): " << e.what(); return 1; }
  • 5. Step 1 Create a range of dates. Copyright Eric Niebler 2015
  • 7. Hello, Range! Copyright Eric Niebler 2015 Range-v3: https://github.com/ericniebler/range-v3
  • 8. Range Views • Begin/end members return iterator/sentinel • Lazy sequence algorithms • Lightweight, non-owning • Composable • Non-mutating Copyright Eric Niebler 2015
  • 9. Range of dates =  Copyright Eric Niebler 2015
  • 10. Range of dates =  Copyright Eric Niebler 2015
  • 11. Range of dates = HACKHACK Copyright Eric Niebler 2015
  • 12. Range of dates = HACKHACK Copyright Eric Niebler 2015
  • 13. Step 2 Group the range of dates into months. Copyright Eric Niebler 2015
  • 14. Group Dates into Months Copyright Eric Niebler 2015
  • 15. Group Dates into Months Copyright Eric Niebler 2015
  • 16. Refactor for Readability Copyright Eric Niebler 2015 Move the group_by expression into its own named adaptor.
  • 17. Built-in Range Views adjacent_remove_if drop_while map split all empty move stride any_range filter partial_sum tail bounded for_each remove_if take c_str generate repeat take_exactly chunk generate_n repeat_n take_while concat group_by replace tokenize const_ indirect replace_if transform counted intersperse reverse unbounded delimit iota single unique drop join slice zip[_with] Copyright Eric Niebler 2015
  • 18. Step 3 Group months into weeks. Copyright Eric Niebler 2015
  • 19. Group Months into Weeks Copyright Eric Niebler 2015
  • 20. Group Months into Weeks Copyright Eric Niebler 2015
  • 21. Step 4 Format the weeks Copyright Eric Niebler 2015
  • 22. Format the Weeks Copyright Eric Niebler 2015
  • 23. Range Actions • Eager sequence algorithms • Can operate on and return containers • Composable • Potentially mutating Copyright Eric Niebler 2015
  • 24. Views vs. Actions Range Views Range Actions Lazy sequence algorithms Eager sequence algorithms Lightweight, non-owning Can operate on and return containers Composable Composable Non-mutating Potentially mutating Copyright Eric Niebler 2015
  • 25. Built-in Range Action drop push_front stable_sort drop_while remove_if stride erase shuffle take insert slice take_while join sort transform push_back split unique Copyright Eric Niebler 2015
  • 26. So Far, So Good Copyright Eric Niebler 2015
  • 27. Step 5 Copyright Eric Niebler 2015 Add month title and padded weeks.
  • 28. Month Title Copyright Eric Niebler 2015 view::concat lazily concatenates ranges. view::single creates a 1-element range.
  • 30. Padding Short Months Copyright Eric Niebler 2015 A formatted month takes as few as four and as many as six lines. For side-by-side display of months, they must all occupy the same vertical space. Pad the short months with empty lines.
  • 31. Padding Short Months Copyright Eric Niebler 2015 view::repeat_n creates an N-element range.
  • 32. Padding Short Months Copyright Eric Niebler 2015
  • 33. So Far, So Good Copyright Eric Niebler 2015 A “year” is a range of “months”. A “month” is a range of strings. Each “month” has exactly 7 lines. by_month() and layout_months() are reusable, and work even if the input range of dates is infinite!
  • 35. Side-by-Side Month Layout Copyright Eric Niebler 2015 J F M A M J J A S O N D J F M A M J J A S
  • 36. Side-by-Side Month Layout 1. Chunk months into groups of 3’s. 2. For each group of 3 months, transpose the “rows” and “columns”. 3. Join the chunks created in step 1. 4. Join the strings of the inner ranges. 5. Print! 6. Take the rest of the day off. Copyright Eric Niebler 2015
  • 37. Chunking: Custom Range Adaptor Copyright Eric Niebler 2015
  • 38. Chunking: Custom Range Adaptor Copyright Eric Niebler 2015
  • 39. Chunking: Custom Range Adaptor Copyright Eric Niebler 2015
  • 40. Chunking: Custom Range Adaptor Copyright Eric Niebler 2015
  • 41. make_pipeable • “chunk” takes two arguments: – The range to chunk – The size of the chunks • “rng | chunk(n)” Copyright Eric Niebler 2015 Must return an object that has overloaded operator|
  • 42. make_pipeable Copyright Eric Niebler 2015 A function of 1 argument Forwards the arg to the function
  • 43. Chunking: Custom Range Adaptor Copyright Eric Niebler 2015
  • 44. Chunking: Custom Range Adaptor Copyright Eric Niebler 2015
  • 45. Transpose Range of Ranges Copyright Eric Niebler 2015
  • 46. Transpose Range of Ranges January Jan Wk 1 Jan Wk 2 Jan Wk 3 Jan Wk 4 Jan Wk 5 Jan Wk 6 February Feb Wk 1 Feb Wk 2 Feb Wk 3 Feb Wk 4 Feb Wk 5 Feb Wk 6 March Mar Wk 1 Mar Wk 2 Mar Wk 3 Mar Wk 4 Mar Wk 5 Mar Wk 6 Copyright Eric Niebler 2015 January February March Jan Wk 1 Feb Wk 1 Mar Wk 1 Jan Wk 2 … January February March Jan Wk 1 Feb Wk 1 Mar Wk 1 Jan Wk 2 Feb Wk 2 Mar Wk 2 Jan Wk 3 Feb Wk 3 Mar Wk 3 Jan Wk 4 Feb Wk 4 Mar Wk 4 Jan Wk 5 Feb Wk 5 Mar Wk 5 Jan Wk 6 Feb Wk 6 Mar Wk 6 1. Interleave 2. Chunk
  • 47. Interleave: Custom Range Facade Copyright Eric Niebler 2015
  • 48. Interleave: Custom Range Facade Copyright Eric Niebler 2015
  • 49. Interleave: Custom Range Facade Copyright Eric Niebler 2015
  • 50. Interleave: Custom Range Facade Copyright Eric Niebler 2015
  • 51. Interleave: Custom Range Facade Copyright Eric Niebler 2015
  • 52. Transpose Range of Ranges Copyright Eric Niebler 2015
  • 53. Side-by-Side Month Layout 1. Chunk months into groups of 3’s. 2. For each group of 3 months, transpose the “rows” and “columns”. 3. Join the chunks created in step 1 4. Join the strings of the inner ranges. 5. Print! 6. Take the rest of the day off. Copyright Eric Niebler 2015
  • 57. Calendar Solution Copyright Eric Niebler 2015 Works with infinite ranges Composable Reusable Can show N months side-by-side No loops!!! Correct by construction.
  • 58. #include <cstddef> #include <string> #include <vector> #include <utility> #include <iostream> #include <stdexcept> #include <functional> #include <boost/format.hpp> #include <boost/lexical_cast.hpp> #include <boost/date_time/gregorian/gregorian.hpp> #include <range/v3/all.hpp> namespace greg = boost::gregorian; using date = greg::date; using day = greg::date_duration; using namespace ranges; using std::cout; namespace boost { namespace gregorian { date &operator++(date &d) { return d = d + day(1); } date operator++(date &d, int) { return ++d - day(1); } }} namespace ranges { template<> struct difference_type<date> { using type = date::duration_type::duration_rep::int_type; }; } CONCEPT_ASSERT(Incrementable<date>()); auto dates_in_year(int year) { return view::iota(date{year,greg::Jan,1}, date{year+1,greg::Jan,1}); } auto by_month() { return view::group_by([](date a, date b) { return a.month() == b.month(); }); } auto by_week() { return view::group_by([](date a, date b) { // ++a because week_numer is Mon-Sun and we want Sun-Sat return (++a).week_number() == (++b).week_number(); }); } std::string format_day(date d) { return boost::str(boost::format("%|3|") % d.day()); } // In: Range<Range<date>>: month grouped by weeks. // Out: Range<std::string>: month with formatted weeks. auto format_weeks() { return view::transform([](/*Range<date>*/ auto week) { return boost::str(boost::format("%1%%2%%|22t|") % std::string((int)front(week).day_of_week() * 3, ' ') % (week | view::transform(format_day) | action::join)); }); } // Return a formatted string with the title of the month // corresponding to a date. std::string month_title(date d) { return boost::str(boost::format("%|=22|") % d.month().as_long_string()); } // In: Range<Range<date>>: year of months of days // Out: Range<Range<std::string>>: year of months of formatted wks auto layout_months() { return view::transform([](/*Range<date>*/ auto month) { int week_count = distance(month | by_week()); return view::concat( view::single(month_title(front(month))), month | by_week() | format_weeks(), view::repeat_n(std::string(22,' '),6-week_count)); }); } Copyright Eric Niebler 2015 // In: Range<T> // Out: Range<Range<T>>, where each inner range has $n$ elements. // The last range may have fewer. template<class Rng> class chunk_view : public range_adaptor<chunk_view<Rng>, Rng> { CONCEPT_ASSERT(ForwardIterable<Rng>()); std::size_t n_; friend range_access; class adaptor; adaptor begin_adaptor() { return adaptor{n_, ranges::end(this->base())}; } public: chunk_view() = default; chunk_view(Rng rng, std::size_t n) : range_adaptor_t<chunk_view>(std::move(rng)), n_(n) {} }; template<class Rng> class chunk_view<Rng>::adaptor : public adaptor_base { std::size_t n_; range_sentinel_t<Rng> end_; using adaptor_base::prev; public: adaptor() = default; adaptor(std::size_t n, range_sentinel_t<Rng> end) : n_(n), end_(end) {} auto current(range_iterator_t<Rng> it) const { return view::take(make_range(std::move(it), end_), n_); } void next(range_iterator_t<Rng> &it) { ranges::advance(it, n_, end_); } }; // In: Range<T> // Out: Range<Range<T>>, where each inner range has $n$ elements. // The last range may have fewer. auto chunk(std::size_t n) { return make_pipeable([=](auto&& rng) { using Rng = decltype(rng); return chunk_view<view::all_t<Rng>>{ view::all(std::forward<Rng>(rng)), n}; }); } // Flattens a range of ranges by iterating the inner // ranges in round-robin fashion. template<class Rngs> class interleave_view : public range_facade<interleave_view<Rngs>> { friend range_access; std::vector<range_value_t<Rngs>> rngs_; struct cursor; cursor begin_cursor() { return {0, &rngs_, view::transform(rngs_, ranges::begin)}; } public: interleave_view() = default; explicit interleave_view(Rngs rngs) : rngs_(std::move(rngs)) {} }; template<class Rngs> struct interleave_view<Rngs>::cursor { std::size_t n_; std::vector<range_value_t<Rngs>> *rngs_; std::vector<range_iterator_t<range_value_t<Rngs>>> its_; decltype(auto) current() const { return *its_[n_]; } void next() { if(0 == ((++n_) %= its_.size())) for_each(its_, [](auto& it){ ++it; }); } bool done() const { return n_ == 0 && its_.end() != mismatch(its_, view::transform(*rngs_, ranges::end), std::not_equal_to<>()).first; } CONCEPT_REQUIRES(ForwardIterable<range_value_t<Rngs>>()) bool equal(cursor const& that) const { return n_ == that.n_ && its_ == that.its_; } }; // In: Range<Range<T>> // Out: Range<T>, flattened by walking the ranges // round-robin fashion. auto interleave() { return make_pipeable([](auto&& rngs) { using Rngs = decltype(rngs); return interleave_view<view::all_t<Rngs>>( view::all(std::forward<Rngs>(rngs))); }); } // In: Range<Range<T>> // Out: Range<Range<T>>, transposing the rows and columns. auto transpose() { return make_pipeable([](auto&& rngs) { using Rngs = decltype(rngs); CONCEPT_ASSERT(ForwardIterable<Rngs>()); return std::forward<Rngs>(rngs) | interleave() | chunk(distance(rngs)); }); } // In: Range<Range<Range<string>>> // Out: Range<Range<Range<string>>>, transposing months. auto transpose_months() { return view::transform([](/*Range<Range<string>>*/ auto rng) { return rng | transpose(); }); } // In: Range<Range<string>> // Out: Range<string>, joining the strings of the inner ranges auto join_months() { return view::transform([](/*Range<string>*/ auto rng) { return action::join(rng); }); } int main(int argc, char *argv[]) try { if(argc < 2) { std::cerr << "Please enter the year to format.n"; std::cerr << boost::format(" Usage: %1% <year>n") % argv[0]; return 1; } int year = boost::lexical_cast<int>(argv[1]); int months_per_line = 3; auto calendar = // Make a range of all the dates in a year: dates_in_year(year) // Group the dates by month: | by_month() // Format the month into a range of strings: | layout_months() // Group the months that belong side-by-side: | chunk(months_per_line) // Transpose the rows and columns of the size-by-side months: | transpose_months() // Ungroup the side-by-side months: | view::join // Join the strings of the transposed months: | join_months(); // Write the result to stdout: copy(calendar, ostream_iterator<>(std::cout, "n")); } catch(std::exception &e) { std::cerr << "ERROR: Unhandled exceptionn"; std::cerr << " what(): " << e.what(); return 1; }
  • 59. Ranges and Standardization Copyright Eric Niebler 2015 Feature Already Proposed? Will be Proposed? Range concepts Range algorithms View adaptors Range actions Façade/Adaptor helpers
  • 60. Copyright Eric Niebler 2015 Initial proposal of the design.2014 Oct Cursory review of concepts and algorithms.2015 May Detailed wording review of concepts and algorithms. Draft other range-related proposals[1]. Present Vote initial wording into a draft TS. Review wording of other proposals. 2015 Oct (??) [1] proxy iterators TS is approved.??? TS is merged into C++XY as STL2.??? Standardization Timeline Even more range-related proposals[2].Next year(s) [2] Infinite ranges, range views and actions, façade, adaptor.
  • 61. Find Out More • N4128 • High-level design, rationale, comparative analysis • http://www.open- std.org/jtc1/sc22/wg21/docs/papers/2014/n4128.html • N4382 • Standard wording for concepts, iterators, algorithms • http://www.open- std.org/JTC1/SC22/WG21/docs/papers/2015/n4382.pdf • Range v3 library • C++11 implementation • http://www.github.com/ericniebler/range-v3 Copyright Eric Niebler 2015

Editor's Notes

  1. Range-based programs are declarative and functional. Not stateful!
  2. Declarative, mostly functional. One if statement, no loops, little state.