Skip to content

Commit

Permalink
Synced the whole chapter03
Browse files Browse the repository at this point in the history
  • Loading branch information
apolukhin committed Apr 16, 2017
1 parent 59b6e84 commit f64ec38
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 37 deletions.
25 changes: 13 additions & 12 deletions Chapter03/05_pointer_cast/main.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
struct base {
struct base {
virtual void some_methods() = 0;
virtual ~base();
};
struct derived: public base {
};

struct derived: public base {
void some_methods() /*override*/;
virtual void derived_method() const;
~derived() /*override*/;
};

~derived() /*override*/;
};


#include <boost/shared_ptr.hpp>
Expand All @@ -26,7 +26,7 @@ void trying_hard_to_pass_derived() {
// Oops! Compile time error:
// could not convert ‘d’ to ‘boost::shared_ptr<const derived>’.
im_accepting_derived(d);
im_accepting_derived(d);
}
*/
Expand All @@ -46,10 +46,11 @@ void trying_hard_to_pass_derived2() {
}

d->derived_method();
im_accepting_derived(d);
im_accepting_derived(d);
}

int main() {
trying_hard_to_pass_derived2();
}


Expand All @@ -58,12 +59,12 @@ int main() {

#include <assert.h>
bool g_derived_was_called = false;
base::~base() {
base::~base() {
assert(g_derived_was_called);
}

void derived::derived_method() const {
g_derived_was_called = true;
void derived::derived_method() const {
g_derived_was_called = true;
}

void derived::some_methods() {}
Expand Down
18 changes: 9 additions & 9 deletions Chapter03/06_polymorphic_cast/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ struct banana: public object {
virtual ~banana(){}
};

struct pidgin: public object {
void fly() const {}
virtual ~pidgin(){}
struct penguin: public object {
bool try_to_fly() const {
return false; // penguins do not fly
}
virtual ~penguin(){}
};

object* try_produce_banana();
Expand All @@ -25,6 +27,7 @@ void try_eat_banana_impl1() {
dynamic_cast<const banana&>(*obj).eat();
}

#include <boost/cast.hpp>
void try_eat_banana_impl2() {
const object* obj = try_produce_banana();
boost::polymorphic_cast<const banana*>(obj)->eat();
Expand All @@ -33,24 +36,22 @@ void try_eat_banana_impl2() {


object* try_produce_banana() {
static pidgin pidg;
static penguin peng;
static banana banan;
static int i = 0;
++ i;
if (i == 3 || i == 6) {
return 0;
} else if (i == 2 || i == 5) {
return &pidg;
return &peng;
}
return &banan;
}

#include <iostream>
using namespace std;

int main()
{

int main() {
try_eat_banana_impl1();

try {
Expand All @@ -73,6 +74,5 @@ int main()
try_eat_banana_impl2();
assert(false);
} catch(...){}
return 0;
}

82 changes: 66 additions & 16 deletions Chapter03/07_spirit/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <assert.h>
#include <boost/spirit/include/qi.hpp>

struct date {
unsigned short year;
Expand All @@ -20,14 +20,18 @@ date parse_date_time1(const std::string& s) {
date res;
const char* first = s.data();
const char* const end = first + s.size();
bool success = boost::spirit::qi::parse(first, end,
ushort_[ ref(res.year) = _1 ] >> char_('-') >> ushort_[ ref(res.month) = _1 ] >> char_('-') >> ushort_[ ref(res.day) = _1 ]
const bool success = boost::spirit::qi::parse(first, end,

// Implementation of 'full-date' rule from EBNF grammar.
ushort_[ ref(res.year) = _1 ] >> char_('-')
>> ushort_[ ref(res.month) = _1 ] >> char_('-')
>> ushort_[ ref(res.day) = _1 ]

);

if (!success || first != end) {
throw std::logic_error("Parsing failed");
}

return res;
}

Expand All @@ -37,42 +41,88 @@ date parse_date_time2(const std::string& s) {
using boost::spirit::qi::char_;
using boost::phoenix::ref;

date res;

// Use unsigned short as output type, require Radix 10, and from 2 to 2 digits
uint_parser<unsigned short, 10, 2, 2> u2_;

// Use unsigned short as output type, require Radix 10, and from 4 to 4 digits
uint_parser<unsigned short, 10, 4, 4> u4_;

const char* first = s.data();
const char* const end = first + s.size();
const bool success = boost::spirit::qi::parse(first, end,

u4_ [ ref(res.year) = _1 ] >> char_('-')
>> u2_ [ ref(res.month) = _1 ] >> char_('-')
>> u2_ [ ref(res.day) = _1 ]

);
if (!success || first != end) {
throw std::logic_error("Parsing failed");
}
return res;
}

#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_CXX11_LAMBDAS)

date parse_date_time2_cxx(const std::string& s) {
using boost::spirit::qi::uint_parser;
using boost::spirit::qi::char_;

date res;

// Use unsigned short as output type, require Radix 10, and from 2 to 2 digits
uint_parser<unsigned short, 10, 2, 2> u2_;

// Use unsigned short as output type, require Radix 10, and from 4 to 4 digits
uint_parser<unsigned short, 10, 4, 4> u4_;

const auto y = [&res](unsigned short s) { res.year = s; };
const auto m = [&res](unsigned short s) { res.month = s; };
const auto d = [&res](unsigned short s) { res.day = s; };

const char* first = s.data();
const char* const end = first + s.size();
bool success = boost::spirit::qi::parse(first, end,
u4_ [ ref(res.year) = _1 ] >> char_('-') >> u2_ [ ref(res.month) = _1 ] >> char_('-') >> u2_ [ ref(res.day) = _1 ]
const bool success = boost::spirit::qi::parse(first, end,
u4_ [y] >> char_('-') >> u2_ [m] >> char_('-') >> u2_ [d]
);

if (!success || first != end) {
throw std::logic_error("Parsing failed");
}

return res;
}

#endif

int main() {
date d = parse_date_time1("2012-12-31");
assert(d.year == 2012);
{
const date d = parse_date_time1("2017-12-31");
assert(d.year == 2017);
assert(d.month == 12);
assert(d.day == 31);
}

parse_date_time2("2012-12-31");
assert(d.year == 2012);
assert(d.month == 12);
assert(d.day == 31);
{
const date d = parse_date_time2("2017-11-21");
assert(d.year == 2017);
assert(d.month == 11);
assert(d.day == 21);
}

try {
parse_date_time2("12345-12-31");
assert(false);
}catch (const std::logic_error&) {}
}

// ushort_[ [&res](unsigned short s) {res.year = s;} ] >> char_('-') >> ushort_[ ref(res.month) = _1 ] >> char_('-') >> ushort_[ ref(res.day) = _1 ]

#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_CXX11_LAMBDAS)
{
const date d = parse_date_time2_cxx("1988-10-09");
assert(d.year == 1988);
assert(d.month == 10);
assert(d.day == 9);
}
#endif

}

0 comments on commit f64ec38

Please sign in to comment.