123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- // Copyright (C) 2008-2018 Lorenzo Caminiti
- // Distributed under the Boost Software License, Version 1.0 (see accompanying
- // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
- // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
- #include <boost/contract.hpp>
- #include <boost/optional.hpp>
- #include <string>
- #include <sstream>
- #include <cassert>
- class lines {
- public:
- virtual std::string str(boost::contract::virtual_* v = 0) const = 0;
- virtual std::string& str(boost::contract::virtual_* v = 0) = 0;
-
- virtual void put(std::string const& x,
- boost::contract::virtual_* v = 0) = 0;
- virtual void put(char x, boost::contract::virtual_* v = 0) = 0;
-
- virtual void put(int x, bool tab = false,
- boost::contract::virtual_* v = 0) = 0;
- };
- std::string lines::str(boost::contract::virtual_* v) const {
- std::string result;
- boost::contract::check c = boost::contract::public_function(v, result, this)
- .postcondition([&] (std::string const& result) {
- if(result != "") BOOST_CONTRACT_ASSERT(*result.rbegin() == '\n');
- })
- ;
- assert(false);
- return result;
- }
- std::string& lines::str(boost::contract::virtual_* v) {
- boost::optional<std::string&> result;
- boost::contract::check c = boost::contract::public_function(v, result, this)
- .postcondition([&] (boost::optional<std::string const&> const& result) {
- if(*result != "") BOOST_CONTRACT_ASSERT(*result->rbegin() == '\n');
- })
- ;
- assert(false);
- return *result;
- }
- void lines::put(std::string const& x, boost::contract::virtual_* v) {
- boost::contract::check c = boost::contract::public_function(v, this)
- .precondition([&] {
- BOOST_CONTRACT_ASSERT(*x.rbegin() != '\n');
- })
- ;
- assert(false);
- }
- void lines::put(char x, boost::contract::virtual_* v) {
- boost::contract::check c = boost::contract::public_function(v, this)
- .precondition([&] {
- BOOST_CONTRACT_ASSERT(x != '\n');
- })
- ;
- assert(false);
- }
- void lines::put(int x, bool tab,
- boost::contract::virtual_* v) {
- boost::contract::check c = boost::contract::public_function(v, this)
- .precondition([&] {
- BOOST_CONTRACT_ASSERT(x >= 0);
- })
- ;
- assert(false);
- }
- //[overload
- class string_lines
- #define BASES public lines
- : BASES
- {
- public:
- typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
- #undef BASES
-
- BOOST_CONTRACT_OVERRIDES(str) // Invoked only once for all `str` overloads.
-
- std::string str(boost::contract::virtual_* v = 0) const /* override */ {
- std::string result;
- boost::contract::check c = boost::contract::public_function<
- override_str>(
- v, result,
- // `static_cast` resolves overloaded function pointer ambiguities.
- static_cast<std::string (string_lines::*)(
- boost::contract::virtual_*) const>(&string_lines::str),
- this
- );
- return result = str_;
- }
-
- // Overload on (absence of) `const` qualifier.
- std::string& str(boost::contract::virtual_* v = 0) /* override */ {
- boost::contract::check c = boost::contract::public_function<
- override_str>(
- v, str_,
- // `static_cast` resolves overloaded function pointer ambiguities.
- static_cast<std::string& (string_lines::*)(
- boost::contract::virtual_*)>(&string_lines::str),
- this
- );
- return str_;
- }
-
- BOOST_CONTRACT_OVERRIDES(put) // Invoked only once for all `put` overloads.
- void put(std::string const& x,
- boost::contract::virtual_* v = 0) /* override */ {
- boost::contract::old_ptr<std::string> old_str =
- BOOST_CONTRACT_OLDOF(v, str());
- boost::contract::check c = boost::contract::public_function<
- override_put>(
- v,
- // `static_cast` resolves overloaded function pointer ambiguities.
- static_cast<void (string_lines::*)(std::string const&,
- boost::contract::virtual_*)>(&string_lines::put),
- this, x
- )
- .postcondition([&] {
- BOOST_CONTRACT_ASSERT(str() == *old_str + x + '\n');
- })
- ;
- str_ = str_ + x + '\n';
- }
-
- // Overload on argument type.
- void put(char x, boost::contract::virtual_* v = 0) /* override */ {
- boost::contract::old_ptr<std::string> old_str =
- BOOST_CONTRACT_OLDOF(v, str());
- boost::contract::check c = boost::contract::public_function<
- override_put>(
- v,
- // `static_cast` resolves overloaded function pointer ambiguities.
- static_cast<void (string_lines::*)(char,
- boost::contract::virtual_*)>(&string_lines::put),
- this, x
- )
- .postcondition([&] {
- BOOST_CONTRACT_ASSERT(str() == *old_str + x + '\n');
- })
- ;
-
- str_ = str_ + x + '\n';
- }
-
- // Overload on argument type and arity (also with default parameter).
- void put(int x, bool tab = false,
- boost::contract::virtual_* v = 0) /* override */ {
- boost::contract::old_ptr<std::string> old_str =
- BOOST_CONTRACT_OLDOF(v, str());
- boost::contract::check c = boost::contract::public_function<
- override_put>(
- v,
- // `static_cast` resolves overloaded function pointer ambiguities.
- static_cast<void (string_lines::*)(int, bool,
- boost::contract::virtual_*)>(&string_lines::put),
- this, x, tab
- )
- .postcondition([&] {
- std::ostringstream s;
- s << x;
- BOOST_CONTRACT_ASSERT(
- str() == *old_str + (tab ? "\t" : "") + s.str() + '\n');
- })
- ;
- std::ostringstream s;
- s << str_ << (tab ? "\t" : "") << x << '\n';
- str_ = s.str();
- }
- private:
- std::string str_;
- };
- //]
- int main() {
- string_lines s;
- s.put("abc");
- assert(s.str() == "abc\n");
- s.put('x');
- assert(s.str() == "abc\nx\n");
- s.put(10);
- assert(s.str() == "abc\nx\n10\n");
- s.put(20, true);
- lines const& l = s;
- assert(l.str() == "abc\nx\n10\n\t20\n");
- return 0;
- }
|