Commit 99c26cbb by Szeberényi Imre

v0

parents
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="CppMonoton" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/STLMonoton" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/STLMonoton" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-pedantic" />
<Add option="-std=c++11" />
<Add option="-Wall" />
<Add option="-Werror" />
</Compiler>
<Unit filename="fancy_iterators.hpp" />
<Unit filename="gtest_lite.h" />
<Unit filename="monoton.hpp" />
<Unit filename="monoton_test.cpp" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>
/*
* \file fancy_iterators.hpp
*
*/
#ifndef FANCY_ITERATORS_HPP
#define FANCY_ITERATORS_HPP
/// counting iterator.
/// Végtelen számláló.
/// Olyan típusokra példányosítható, aminek van pre-inkremens operátora.
template <typename T>
class counting_iterator : public std::iterator<std::input_iterator_tag, T>{
/// öröklés: az std algoritmusok igy ellenőrizni tudják a tulajdonságokat
T t;
public:
/// Konstruktor
/// @param t - kezdőérték
counting_iterator(T t = T()) : t(t) {}
/// Összehasonlító operátorok
bool operator==(const counting_iterator& rhs) const { return t == rhs.t; }
bool operator!=(const counting_iterator& rhs) const { return !operator==(rhs); }
/// pre-inkremens
/// csak hatékonyság miatt ref. visszatérésű
/// értelmetlen balértékként használni
const counting_iterator& operator++() { ++t; return *this; }
/// post-inkremens
counting_iterator operator++(int) {
counting_iterator tmp = *this; /// eltesszük a jelenlegi értéket
operator++();
return tmp; /// léptetés előttivel tér vissza
}
/// dereferálás
/// nem engedjük balértékként használni, ne változtathassa meg a sorozatot
const T& operator*() const { return t; }
/// szelekció pointerrel, ami címet kell, hogy adjon
/// csak formai, mert csak privát adattag lenne elérhető, így nem lehet használni
const T* operator->() const { return &operator*(); }
};
#endif // FANCY_ITERATORS_HPP
#ifndef GTEST_LITE_H
#define GTEST_LITE_H
/**
* \file gtest_lite.h (v3/2019)
*
* Google gtest keretrendszerhez hasonló rendszer.
* Sz.I. 2015., 2016., 2017. (_Has_X)
* Sz.I. 2018 (template), ENDM, ENDMsg, nullptr_t
* Sz.I. 2019 singleton
*
* A tesztelés legalapvetőbb funkcióit támogató függvények és makrók.
* Nem szálbiztos megvalósítás.
*
*
* Szabadon felhasználható, bővíthető.
*
* Használati példa:
* Teszteljük az f(x)=2*x függvényt:
* int f(int x) { return 2*x; }
*
* int main() {
* TEST(TeszEsetNeve, TesztNeve)
* EXPECT_EQ(0, f(0));
* EXPECT_EQ(4, f(2)) << "A függvény hibás eredményt adott" << std::endl;
* ...
* END
* ...
*
* A működés részleteinek megértése szorgalmi feladat.
*/
#include <iostream>
#include <cassert>
#include <cmath>
#include <cstring>
#include <limits>
#include <string>
#include <fstream>
#ifdef MEMTRACE
#include "memtrace.h"
#endif
// Két makró az egyes tesztek elé és mögé:
// A két makró a kapcsos zárójelekkel egy új blokkot hoz létre, amiben
// a nevek lokálisak, így elkerülhető a névütközés.
/// Teszt kezdete. A makró paraméterezése hasonlít a gtest
/// paraméterezéséhez. Így az itt elkészített testek könnyen átemelhetők
/// a gtest keretrendszerbe.
/// @param C - teszteset neve (csak a gtest kompatibilitás miatt van külön neve az eseteknek)
/// @param N - teszt neve
#define TEST(C, N) { gtest_lite::test.begin(#C"."#N);
/// Teszteset vége.
#define END gtest_lite::test.end(); }
/// Teszteset vége allokált blokkok számának összehasonlításával
/// Ez az ellenőrzés nem bomba biztos.
#define ENDM gtest_lite::test.end(true); }
/// Teszteset vége allokált blokkok számának összehasonlításával
/// Ez az ellenőrzés nem bomba biztos.
/// Ha hiba van kiírja az üzenetet.
#define ENDMsg(t) gtest_lite::test.end(true) << t << std::endl; }
// Eredmények vizsgálatát segítő makrók.
// A paraméterek és a funkciók a gtest keretrendszerrel megegyeznek.
/// Sikeres teszt makrója
#define SUCCEED() gtest_lite::test.expect(true, __FILE__, __LINE__, "SUCCEED()", true)
/// Sikertelen teszt makrója
#define FAIL() gtest_lite::test.expect(false, __FILE__, __LINE__, "FAIL()", true)
/// Azonosságot elváró makró
#define EXPECT_EQ(expected, actual) gtest_lite::EXPECT_(expected, actual, gtest_lite::eq, __FILE__, __LINE__, "EXPECT_EQ(" #expected ", " #actual ")" )
/// Eltérést elváró makró
#define EXPECT_NE(expected, actual) gtest_lite::EXPECT_(expected, actual, gtest_lite::ne, __FILE__, __LINE__, "EXPECT_NE(" #expected ", " #actual ")", "etalon" )
/// Kisebb, vagy egyenlő relációt elváró makró
#define EXPECT_LE(expected, actual) gtest_lite::EXPECT_(expected, actual, gtest_lite::le, __FILE__, __LINE__, "EXPECT_LE(" #expected ", " #actual ")", "etalon" )
/// Kisebb, mint relációt elváró makró
#define EXPECT_LT(expected, actual) gtest_lite::EXPECT_(expected, actual, gtest_lite::lt, __FILE__, __LINE__, "EXPECT_LT(" #expected ", " #actual ")", "etalon" )
/// Nagyobb, vagy egyenlő relációt elváró makró
#define EXPECT_GE(expected, actual) gtest_lite::EXPECT_(expected, actual, gtest_lite::ge, __FILE__, __LINE__, "EXPECT_GE(" #expected ", " #actual ")", "etalon" )
/// Nagyobb, mint relációt elváró makró
#define EXPECT_GT(expected, actual) gtest_lite::EXPECT_(expected, actual, gtest_lite::gt, __FILE__, __LINE__, "EXPECT_GT(" #expected ", " #actual ")", "etalon" )
/// Igaz értéket elváró makró
#define EXPECT_TRUE(actual) gtest_lite::EXPECT_(true, actual, gtest_lite::eq, __FILE__, __LINE__, "EXPECT_TRUE(" #actual ")" )
/// Hamis értéket elváró makró
#define EXPECT_FALSE(actual) gtest_lite::EXPECT_(false, actual, gtest_lite::eq, __FILE__, __LINE__, "EXPECT_FALSE(" #actual ")" )
/// Valós számok azonosságát elváró makró
#define EXPECT_FLOAT_EQ(expected, actual) gtest_lite::EXPECT_(expected, actual, gtest_lite::almostEQ, __FILE__, __LINE__, "EXPECT_FLOAT_EQ(" #expected ", " #actual ")" )
/// Valós számok azonosságát elváró makró
#define EXPECT_DOUBLE_EQ(expected, actual) gtest_lite::EXPECT_(expected, actual, gtest_lite::almostEQ, __FILE__, __LINE__, "EXPECT_DOUBLE_EQ(" #expected ", " #actual ")" )
/// C stringek (const char *) azonosságát tesztelő makró
#define EXPECT_STREQ(expected, actual) gtest_lite::EXPECTSTR(expected, actual, gtest_lite::eqstr, __FILE__, __LINE__, "EXPECT_STREQ(" #expected ", " #actual ")" )
/// C stringek (const char *) eltéréset tesztelő makró
#define EXPECT_STRNE(expected, actual) gtest_lite::EXPECTSTR(expected, actual, gtest_lite::nestr, __FILE__, __LINE__, "EXPECT_STRNE(" #expected ", " #actual ")", "etalon" )
/// Kivételt várunk
#define EXPECT_THROW(statement, exception_type) try { gtest_lite::test.tmp = false; statement; } \
catch (exception_type) { gtest_lite::test.tmp = true; } \
catch (...) { } \
EXPECTTHROW(statement, "kivetelt dob.", "nem dobott '"#exception_type"' kivetelt.")
/// Kivételt várunk
#define EXPECT_ANY_THROW(statement) try { gtest_lite::test.tmp = false; statement; } \
catch (...) { gtest_lite::test.tmp = true; } \
EXPECTTHROW(statement, "kivetelt dob.", "nem dobott kivetelt.")
/// Nem várunk kivételt
#define EXPECT_NO_THROW(statement) try { gtest_lite::test.tmp = true; statement; } \
catch (...) { gtest_lite::test.tmp = false; }\
EXPECTTHROW(statement, "nem dob kivetelt.", "kivetelt dobott.")
/// Nem várunk kivételt gtest kompatibilitás miatt
#define ASSERT_NO_THROW(statement) try { gtest_lite::test.tmp = true; statement; } \
catch (...) { gtest_lite::test.tmp = false; }\
EXPECTTHROW(statement, "nem dob kivetelt.", "kivetelt dobott.")
/// Kivételt várunk és továbbdobjuk -- ilyen nincs a gtest-ben
#define EXPECT_THROW_THROW(statement, exception_type) try { gtest_lite::test.tmp = false; statement; } \
catch (exception_type) { gtest_lite::test.tmp = true; throw; } \
EXPECTTHROW(statement, "kivetelt dob.", "nem dobott '"#exception_type"' kivetelt.")
/// Segédmakró egy adattag, vagy tagfüggvény létezésének tesztelésére futási időben
/// Ötlet:
/// https://cpptalk.wordpress.com/2009/09/12/substitution-failure-is-not-an-error-2
/// Használat:
/// CREATE_Has_(size)
/// ... if (Has_size<std::string>::member)...
#define CREATE_Has_(X) \
template<typename T> struct _Has_##X { \
struct Fallback { int X; }; \
struct Derived : T, Fallback {}; \
template<typename C, C> struct ChT; \
template<typename D> static char (&f(ChT<int Fallback::*, &D::X>*))[1]; \
template<typename D> static char (&f(...))[2]; \
static bool const member = sizeof(f<Derived>(0)) == 2; \
};
/// Segédfüggvény egy publikus adattag, vagy tagfüggvény létezésének tesztelésére
/// fordítási időben
inline void hasMember(...) {}
/// Segédsablon típuskonverzió futás közbeni ellenőrzésere
template <typename F, typename T>
struct _Is_Types {
template<typename D> static char (&f(D))[1];
template<typename D> static char (&f(...))[2];
static bool const convertable = sizeof(f<T>(F())) == 1;
};
/// -----------------------------------
/// Belső megvalósításhoz tartozó makrók, és osztályok.
/// Nem célszerű közvetlenül használni, vagy módosítani
/// -----------------------------------
/// EXPECTTHROW: kivételkezelés
#define EXPECTTHROW(statement, exp, act) gtest_lite::test.expect(gtest_lite::test.tmp, __FILE__, __LINE__, #statement) \
<< "** Az utasitas " << (act) \
<< "\n** Azt vartuk, hogy " << (exp) << std::endl
#ifdef CPORTA
#define GTINIT(is) \
int magic; \
is >> magic;
#else
#define GTINIT(IS)
#endif // CPORTA
#ifdef CPORTA
#define GTEND(os) \
os << magic << (gtest_lite::test.fail() ? " NO" : " OK?") << std::endl;
#else
#define GTEND(os)
#endif // CPORTA
/// gtest_lite: a keretrendszer függvényinek és objektumainak névtere
namespace gtest_lite {
/// Tesztek állapotát tároló osztály.
/// Egyetlen egy statikus példány keletkezik, aminek a
/// destruktora a futás végén hívódik meg.
struct Test {
int sum; ///< tesztek számlálója
int failed; ///< hibás tesztek
int ablocks; ///< allokált blokkok száma
bool status; ///< éppen futó teszt státusza
bool tmp; ///< temp a kivételkezeléshez;
std::string name; ///< éppen futó teszt neve
std::fstream null; ///< nyelő, ha nem kell kiírni semmit
static Test& getTest() {
static Test instance;///< egyedüli (singleton) példány
return instance;
}
private: /// singleton minta miatt
Test() :sum(0), failed(0), status(false), null("/dev/null") {}
Test(const Test&);
void operator=(const Test&);
public:
/// Teszt kezdete
void begin(const char *n) {
name = n; status = true;
#ifdef MEMTRACE
ablocks = memtrace::allocated_blocks();
#endif
#ifndef CPORTA
std::cerr << "\n---> " << name << std::endl;
#endif // CPORTA
++sum;
}
/// Teszt vége
std::ostream& end(bool memchk = false) {
#ifdef MEMTRACE
if (memchk && ablocks != memtrace::allocated_blocks()) {
status = false;
return std::cerr << "** Lehet, hogy nem szabaditott fel minden memoriat! **" << std::endl;
}
#endif
#ifdef CPORTA
if (!status)
#endif // CPORTA
std::cerr << (status ? " SIKERES" : "** HIBAS ****") << "\t" << name << " <---" << std::endl;
if (!status)
return std::cerr;
else
return null;
}
bool fail() { return failed; }
/// Eredményt adminisztráló tagfüggvény True a jó eset.
std::ostream& expect(bool st, const char *file, int line, const char *expr, bool pr = false) {
if (!st) {
++failed;
status = false;
}
if (!st || pr) {
std::string str(file);
size_t i = str.rfind("\\");
if (i == std::string::npos) i = str.rfind("/");
if (i == std::string::npos) i = 0; else i++;
return std::cerr << "\n**** " << &file[i] << "(" << line << "): " << expr << " ****" << std::endl;
}
return null;
}
/// Destruktor
~Test() {
#ifdef CPORTA
if (failed)
#endif // CPORTA
std::cerr << "\n==== TESZT VEGE ==== HIBAS/OSSZES: " << failed << "/" << sum << std::endl;
}
};
/// A statikus referencia minden fordítási egységben keletkezik, de
/// mindegyik egyetlen példányra fog hivatkozni a singleton minta miatt
static Test& test = Test::getTest();
/// általános sablon a várt értékhez.
template <typename T1, typename T2>
std::ostream& EXPECT_(T1 exp, T2 act, bool (*pred)(T1, T2), const char *file, int line,
const char *expr, const char *lhs = "elvart", const char *rhs = "aktual") {
return test.expect(pred(exp, act), file, line, expr)
<< "** " << lhs << ": " << std::boolalpha << exp
<< "\n** " << rhs << ": " << std::boolalpha << act << std::endl;
}
/// pointerre specializált sablon a várt értékhez.
template <typename T1, typename T2>
std::ostream& EXPECT_(T1* exp, T2* act, bool (*pred)(T1*, T2*), const char *file, int line,
const char *expr, const char *lhs = "elvart", const char *rhs = "aktual") {
return test.expect(pred(exp, act), file, line, expr)
<< "** " << lhs << ": " << (void*) exp
<< "\n** " << rhs << ": " << (void*) act << std::endl;
}
#if __cplusplus >= 201103L
/// nullptr-re specializált sablon a várt értékhez.
template <typename T1>
std::ostream& EXPECT_(T1* exp, std::nullptr_t act, bool (*pred)(T1*, std::nullptr_t), const char *file, int line,
const char *expr, const char *lhs = "elvart", const char *rhs = "aktual") {
return test.expect(pred(exp, act), file, line, expr)
<< "** " << lhs << ": " << (void*) exp
<< "\n** " << rhs << ": " << (void*) act << std::endl;
}
#endif
/// stringek összehasonlításához.
/// azért nem spec. mert a sima EQ-ra másként kell működnie.
inline
std::ostream& EXPECTSTR(const char *exp, const char *act, bool (*pred)(const char*, const char*), const char *file, int line,
const char *expr, const char *lhs = "elvart", const char *rhs = "aktual") {
return test.expect(pred(exp, act), file, line, expr)
<< "** " << lhs << ": " << (exp == NULL ? "NULL pointer" : std::string("\"") + exp + std::string("\""))
<< "\n** " << rhs << ": " << (act == NULL ? "NULL pointer" : std::string("\"") + act + std::string("\"")) << std::endl;
}
/// segéd sablonok a relációkhoz.
/// azért nem STL (algorithm), mert csak a függvény lehet, hogy menjen a deduckció
template <typename T1, typename T2>
bool eq(T1 a, T2 b) { return a == b; }
inline
bool eqstr(const char *a, const char *b) {
if (a != NULL && b != NULL)
return strcmp(a, b) == 0;
return false;
}
template <typename T1, typename T2>
bool ne(T1 a, T2 b) { return a != b; }
inline
bool nestr(const char *a, const char *b) {
if (a != NULL && b != NULL)
return strcmp(a, b) != 0;
return false;
}
template <typename T1, typename T2>
bool le(T1 a, T2 b) { return a <= b; }
template <typename T1, typename T2>
bool lt(T1 a, T2 b) { return a < b; }
template <typename T1, typename T2>
bool ge(T1 a, T2 b) { return a >= b; }
template <typename T1, typename T2>
bool gt(T1 a, T2 b) { return a > b; }
/// Segédsablon valós számok összehasonlításához
/// Nem bombabiztos, de nekünk most jó lesz
/// Elméleti hátér:
/// http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
template <typename T>
bool almostEQ(T a, T b) {
// eps: ha a relatív, vagy abszolút hiba ettől kisebb, akkor elfogadjuk
T eps = 10 * std::numeric_limits<T>::epsilon(); // 10-szer a legkisebb érték
if (a == b) return true;
if (fabs(a - b) < eps)
return true;
double aa = fabs(a);
double ba = fabs(b);
if (aa < ba) {
aa = ba;
ba = fabs(a);
}
return (aa - ba) < aa * eps;
}
} // namespace gtest_lite
#endif // GTEST_LITE_H
#ifndef MONOTON_HPP
#define MONOTON_HPP
#error "Itt készitse el a monoton sablont!"
#endif // MONOTON_HPP
**Készítsen** generikus algoritmust (*monoton*) annak eldöntésére, hogy egy iterátorokkal adott jobbról nyílt intervallum elemei monoton sorozatot alkotnak-e. Az algoritmus harmadik paramétere egy predikátum!
Ezzel a kétoperandusú predikátummal adható meg egy adott elem és az őt megelőző elem viszonya a sorozaton belül.
A sablon használatára mutat példát az alábbi kódrészlet:
std::vector<int> v;
...
if (monoton(v.begin(), v.end(), std::greater<int>()))
std::cout << "Ez a sorozat szigorúan monoton növekvő\n";
else if (monoton(v.begin(), v.end(), std::greater_equal<int>()))
std::cout << "Ez a sorozat monoton növekvő\n";
else if (monoton(v.begin(), v.end(), std::less<int>()))
std::cout << "Ez a sorozat szigorúan monoton csökkenő\n";
else if (monoton(v.begin(), v.end(), std::less_equal<int>()))
std::cout << "Ez a sorozat monoton csökkenő\n";
else
std::cout << "Ez a sorozat nem monoton\n";
**Feladatok:**
1. Töltse le az előkészített projektet az SVN tárolóból!
[https://git.ik.bme.hu/Prog2/ell_feladat/CppMonoton](https://git.ik.bme.hu/Prog2/ell_feladat/CppMonoton.git)
2. Készítse el a **monoton** sablont a *monoton.hpp* állományban! Az algoritmust úgy valósítsa meg hogy csak az
ún. *Input Iterator*-okra jellemző műveleteket használja (konstruktor, másoló, értékadó, ++, ==, != ++, *, ->).
3. Tesztelje a megadott tesztprogrammal a sablont!
4. Amennyiben a tesztek jól futnak, töltse fel a *JPorta* feladatbeadó rendszerbe a **monoton.hpp** fájlt!
/**
* \file: monoton_test.cpp
*
* Tesztprogram monoton sablonhoz.
*
* Extra:
* A feladat megoldása mellett érdemes elemezni a tárolók és iterátorok használatát,
* valamint a szignálkezelést.
*
*/
#include <iostream>
#include <csignal>
#include <stdexcept>
#include <string>
#include <vector>
#include <set>
#include <list>
#include <functional>
#include <algorithm>
#include <iterator>
#include <cstdlib>
#include <ctime>
#include "gtest_lite.h"
#include "fancy_iterators.hpp"
#include "monoton.hpp"
using std::cout;
using std::endl;
using std::make_pair;
/// Segédsablon a hiba kiírásához.
/// Egy sorozattárolóból kiír egy intervallumot
/// Az ostream inserterét std::pair esetre definiáljuk. Így könnyen kiíratható
/// egy intervallum egy sorozattárolóból.
/// @param Iter - sablonparaméter: iterátor típusa
/// @param os - ostream ahova kiír
/// @param p - iteratorokból képzett std::pair
template <typename Iter>
std::ostream& operator<<(std::ostream& os, std::pair<Iter, Iter> p) {
os << "** Ezt vizsgaltuk: ";
if (p.first == p.second)
os << "Ures halmaz";
while (p.first != p.second)
os << *p.first++ << ", ";
return os << std::endl;
}
/// Becsapós segédsablon: mindig igazat/vagy hamisat ad
/// Arra jó, hogy elszálljon a program, ha túlfut az iterátor a monoton sablonban.
/// Ha túlfut (last után), akkor van valószínűsége, hogy illegális memóriacímet olvas
template <typename T>
struct const_pred {
bool ret;
const_pred(bool b = true): ret(b) {}
bool operator()(T, T) {
return ret;
}
};
/// Segmentation violation signal kezelése.
/// Akkor keletkezik, ha olyan memóriacímet próbál elérni a program, ami
/// nem a programhoz tartozik, vagy írni akar egy nem írható címre.
/// Mivel az op. rendszertől érkező szignálok nem generálnak kivételt,
/// nekünk kell ezt programozottan megoldani.
/// Ez az út azonban nem minden szigál esetében járható. Az aszinkron szignalok
/// esetében a handlerből indított throw nem biztonságos.
void sigSegv(int signal) {
throw std::out_of_range("Valoszinu lefutott az iteraror a tarolorol!");
}
int main() {
try {
GTINIT(std::cin); // Csak C(J)PORTA működéséhez kell
std::signal(SIGSEGV, sigSegv); /// Signal handler beállítása
/// Üres halmazra szinte minden halmaztulajdonság igaz.
TEST(Test1, Sanity) {
const char* p = "duma";
EXPECT_TRUE(monoton(p, p, std::greater<char>())) << make_pair(p, p); /// hiba esetén kiírjuk az intervallumot
EXPECT_TRUE(monoton(p, p, std::greater_equal<char>())) << make_pair(p, p);
EXPECT_TRUE(monoton(p, p, std::less<char>())) << make_pair(p, p);
EXPECT_TRUE(monoton(p, p, std::less_equal<char>())) << make_pair(p, p);
EXPECT_TRUE(monoton(p, p, const_pred<char>())) << "A tulfutast teszteli" << endl;
EXPECT_TRUE(monoton(p, p, const_pred<char>(false))) << "A tulfutast teszteli" << endl;
} END
/// counting_iterator int típussal
TEST(Test2, counting_iterator) {
counting_iterator<int> b = 10, e = 60; /// szigorúan növekvő sorozat
EXPECT_TRUE(monoton(b, e, std::greater<int>())) << make_pair(b, e);
EXPECT_TRUE(monoton(b, e, std::greater_equal<int>())) << make_pair(b, e);
EXPECT_FALSE(monoton(b, e, std::less<int>())) << make_pair(b, e);
EXPECT_FALSE(monoton(b, e, std::less_equal<int>())) << make_pair(b, e);
EXPECT_TRUE(monoton(b, e, const_pred<int>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(b, e, const_pred<int>(false))) << "A tulfutast teszteli" << endl;
} END
/// int tömb
TEST(Test3, intArray) {
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /// ez is szigorúan növekvő sorozat
EXPECT_TRUE(monoton(a, a+10, std::greater<int>())) << make_pair(a, a+10);
EXPECT_TRUE(monoton(a, a+10, std::greater_equal<int>())) << make_pair(a, a+10);
EXPECT_FALSE(monoton(a, a+10, std::less<int>())) << make_pair(a, a+10);
EXPECT_FALSE(monoton(a, a+10, std::less_equal<int>())) << make_pair(a, a+10);
EXPECT_TRUE(monoton(a, a+10, const_pred<int>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(a, a+10, const_pred<int>(false))) << "A tulfutast teszteli" << endl;
} END
/// Teszteseten kívül deklaráljuk, mert több tesztesetben használjuk
std::vector<int> v;
/// int vector szigorúan monoton
TEST(Test4, intVector) {
counting_iterator<int> b = 20, e = 30; /// ez is szigorúan növekvő sorozat
/// vektorba tesszük és visszafelé iterálunk
v.assign(b, e);
EXPECT_TRUE(monoton(v.rbegin(), v.rend(), std::less<int>())) << make_pair(v.rbegin(), v.rend());
EXPECT_TRUE(monoton(v.rbegin(), v.rend(), std::less_equal<int>())) << make_pair(v.rbegin(), v.rend());
EXPECT_FALSE(monoton(v.rbegin(), v.rend(), std::greater<int>())) << make_pair(v.rbegin(), v.rend());
EXPECT_FALSE(monoton(v.rbegin(), v.rend(), std::greater_equal<int>())) << make_pair(v.rbegin(), v.rend());
EXPECT_TRUE(monoton(v.rbegin(), v.rend(), const_pred<int>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(v.rbegin(), v.rend(), const_pred<int>(false))) << "A tulfutast teszteli" << endl;
EXPECT_TRUE(monoton(v.begin(), v.end(), const_pred<int>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(v.begin(), v.end(), const_pred<int>(false))) << "A tulfutast teszteli" << endl;
} END
/// int
TEST(Test5, intVectorRep1) {
std::vector<int> u = v;
u.insert(u.begin(), *u.begin()); /// elején ismétlődik
EXPECT_FALSE(monoton(u.begin(), u.end(), std::greater<int>())) << make_pair(u.begin(), u.end());
EXPECT_TRUE(monoton(u.begin(), u.end(), std::greater_equal<int>())) << make_pair(u.begin(), u.end());
EXPECT_FALSE(monoton(u.begin(), u.end(), std::less<int>())) << make_pair(u.begin(), u.end());
EXPECT_FALSE(monoton(u.begin(), u.end(), std::less_equal<int>())) << make_pair(u.begin(), u.end());
} END
TEST(Test6, intVectorRep2) {
std::vector<int> u = v;
u.insert(u.end(), *(u.end()-1)); /// végén ismétlődik
EXPECT_FALSE(monoton(u.begin(), u.end(), std::greater<int>())) << make_pair(u.begin(), u.end());
EXPECT_TRUE(monoton(u.begin(), u.end(), std::greater_equal<int>())) << make_pair(u.begin(), u.end());
EXPECT_FALSE(monoton(u.begin(), u.end(), std::less<int>())) << make_pair(u.begin(), u.end());
EXPECT_FALSE(monoton(u.begin(), u.end(), std::less_equal<int>())) << make_pair(u.begin(), u.end());
} END
TEST(Test7, intVectorRep3) {
std::vector<int> u = v;
u.insert(u.begin()+5, 2, *(u.begin()+5)); /// belül ismétlődik 3-szor
EXPECT_FALSE(monoton(u.begin(), u.end(), std::greater<int>())) << make_pair(u.begin(), u.end());
EXPECT_TRUE(monoton(u.begin(), u.end(), std::greater_equal<int>())) << make_pair(u.begin(), u.end());
EXPECT_FALSE(monoton(u.begin(), u.end(), std::less<int>())) << make_pair(u.begin(), u.end());
EXPECT_FALSE(monoton(u.begin(), u.end(), std::less_equal<int>())) << make_pair(u.begin(), u.end());
} END
TEST(Test8, intVectorRep4) {
/// betesszük kétszer a w vektorba rendezve.
std::vector<int> w(2*v.size()); // 2-szer akkora hely kell
std::merge(v.begin(), v.end(), v.begin(), v.end(), w.begin());
EXPECT_FALSE(monoton(w.begin(), w.end(), std::greater<int>())) << make_pair(w.begin(), w.end());
EXPECT_TRUE(monoton(w.begin(), w.end(), std::greater_equal<int>())) << make_pair(w.begin(), w.end());
EXPECT_FALSE(monoton(w.rbegin(), w.rend(), std::less<int>())) << make_pair(w.rbegin(), w.rend());
EXPECT_TRUE(monoton(w.rbegin(), w.rend(), std::less_equal<int>())) << make_pair(w.rbegin(), w.rend());
EXPECT_TRUE(monoton(w.rbegin(), w.rend(), const_pred<int>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(w.rbegin(), w.rend(), const_pred<int>(false))) << "A tulfutast teszteli" << endl;
EXPECT_TRUE(monoton(w.begin(), w.end(), const_pred<int>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(w.begin(), w.end(), const_pred<int>(false))) << "A tulfutast teszteli" << endl;
} END
TEST(Test9, inUpDown) {
/// Betesszük kétszer a w vektorba.
/// Először növekvő, majd csökkenő sorrendben
std::vector<int> w(v.begin(), v.end());
w.insert(w.end(), v.rbegin(), v.rend());
EXPECT_FALSE(monoton(w.begin(), w.end(), std::greater<int>())) << make_pair(w.begin(), w.end());
EXPECT_FALSE(monoton(w.begin(), w.end(), std::greater_equal<int>())) << make_pair(w.begin(), w.end());
EXPECT_FALSE(monoton(w.rbegin(), w.rend(), std::less<int>())) << make_pair(w.rbegin(), w.rend());
EXPECT_FALSE(monoton(w.rbegin(), w.rend(), std::less_equal<int>())) << make_pair(w.rbegin(), w.rend());
EXPECT_TRUE(monoton(w.rbegin(), w.rend(), const_pred<int>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(w.rbegin(), w.rend(), const_pred<int>(false))) << "A tulfutast teszteli" << endl;
EXPECT_TRUE(monoton(w.begin(), w.end(), const_pred<int>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(w.begin(), w.end(), const_pred<int>(false))) << "A tulfutast teszteli" << endl;
} END
/// Teszteseten kívül deklaráljuk, mert több tesztesetben használjuk
std::set<double> s; /// Az std::set kulcs szerint rendezett !
/// hasonló tesztek double halmazzal
TEST(Test10, doubleSet) {
std::srand(std::time(NULL));
int n = rand() % 10 + 10;
while (n--) {
double d = ((double)rand()/RAND_MAX) * 100;
s.insert(d);
}
// A set miatt biztos, hogy szigorúan monoton lesz
EXPECT_TRUE(monoton(s.begin(), s.end(), std::greater<double>())) << make_pair(s.begin(), s.end());
EXPECT_TRUE(monoton(s.rbegin(), s.rend(), std::less<double>())) << make_pair(s.rbegin(), s.rend());
EXPECT_TRUE(monoton(s.rbegin(), s.rend(), const_pred<double>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(s.rbegin(), s.rend(), const_pred<double>(false))) << "A tulfutast teszteli" << endl;
EXPECT_TRUE(monoton(s.begin(), s.end(), const_pred<double>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(s.begin(), s.end(), const_pred<double>(false))) << "A tulfutast teszteli" << endl;
} END
/// hasonló tesztek double listával
TEST(Test11, doubleList) {
// itt áttesszük listába
std::list<double> l(s.begin(), s.end());
EXPECT_TRUE(monoton(l.begin(), l.end(), std::greater<double>())) << make_pair(l.begin(), l.end());
EXPECT_TRUE(monoton(l.rbegin(), l.rend(), std::less<double>())) << make_pair(l.rbegin(), l.rend());
EXPECT_TRUE(monoton(l.rbegin(), l.rend(), const_pred<double>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(l.rbegin(), l.rend(), const_pred<double>(false))) << "A tulfutast teszteli" << endl;
EXPECT_TRUE(monoton(l.begin(), l.end(), const_pred<double>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(l.begin(), l.end(), const_pred<double>(false))) << "A tulfutast teszteli" << endl;
// és elrontjuk a rendezettséget
l.insert(l.end(), s.rbegin(), s.rend());
EXPECT_FALSE(monoton(l.begin(), l.end(), std::greater<double>())) << make_pair(l.begin(), l.end());
EXPECT_FALSE(monoton(l.begin(), l.end(), std::less<double>())) << make_pair(l.rbegin(), l.rend());
EXPECT_TRUE(monoton(l.rbegin(), l.rend(), const_pred<double>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(l.rbegin(), l.rend(), const_pred<double>(false))) << "A tulfutast teszteli" << endl;
EXPECT_TRUE(monoton(l.begin(), l.end(), const_pred<double>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(l.begin(), l.end(), const_pred<double>(false))) << "A tulfutast teszteli" << endl;
} END
/// Sztringgel is megnézzük
TEST(Test12, sring) {
const char *duma[] = { "alma", "meggy", "szilva", "uborka" };
std::vector<std::string> s(duma, duma+4);
std::ostream_iterator<std::string> os(cout, ", ");
std::copy(s.begin(), s.end(), os);
cout << endl;
EXPECT_TRUE(monoton(s.begin(), s.end(), std::greater<std::string>())) << make_pair(s.begin(), s.end());
EXPECT_FALSE(monoton(s.rbegin(), s.rend(), std::greater<std::string>())) << make_pair(s.begin(), s.end());
EXPECT_TRUE(monoton(s.rbegin(), s.rend(), const_pred<std::string>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(s.rbegin(), s.rend(), const_pred<std::string>(false))) << "A tulfutast teszteli" << endl;
EXPECT_TRUE(monoton(s.begin(), s.end(), const_pred<std::string>())) << "A tulfutast teszteli" << endl;
EXPECT_FALSE(monoton(s.begin(), s.end(), const_pred<std::string>(false))) << "A tulfutast teszteli" << endl;
} END
} catch (std::exception& e) {
FAIL() << e.what() << std::endl;
}
/// itt a vége
GTEND(std::cerr); // Csak C(J)PORTA működéséhez kell
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment