19368eea42a1afb01dd44110582f997115b50e742François Gaffie/*
29368eea42a1afb01dd44110582f997115b50e742François Gaffie * Copyright (c) 2011-2014, Intel Corporation
39368eea42a1afb01dd44110582f997115b50e742François Gaffie * All rights reserved.
49368eea42a1afb01dd44110582f997115b50e742François Gaffie *
59368eea42a1afb01dd44110582f997115b50e742François Gaffie * Redistribution and use in source and binary forms, with or without modification,
69368eea42a1afb01dd44110582f997115b50e742François Gaffie * are permitted provided that the following conditions are met:
79368eea42a1afb01dd44110582f997115b50e742François Gaffie *
89368eea42a1afb01dd44110582f997115b50e742François Gaffie * 1. Redistributions of source code must retain the above copyright notice, this
99368eea42a1afb01dd44110582f997115b50e742François Gaffie * list of conditions and the following disclaimer.
109368eea42a1afb01dd44110582f997115b50e742François Gaffie *
119368eea42a1afb01dd44110582f997115b50e742François Gaffie * 2. Redistributions in binary form must reproduce the above copyright notice,
129368eea42a1afb01dd44110582f997115b50e742François Gaffie * this list of conditions and the following disclaimer in the documentation and/or
139368eea42a1afb01dd44110582f997115b50e742François Gaffie * other materials provided with the distribution.
149368eea42a1afb01dd44110582f997115b50e742François Gaffie *
159368eea42a1afb01dd44110582f997115b50e742François Gaffie * 3. Neither the name of the copyright holder nor the names of its contributors
169368eea42a1afb01dd44110582f997115b50e742François Gaffie * may be used to endorse or promote products derived from this software without
179368eea42a1afb01dd44110582f997115b50e742François Gaffie * specific prior written permission.
189368eea42a1afb01dd44110582f997115b50e742François Gaffie *
199368eea42a1afb01dd44110582f997115b50e742François Gaffie * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
209368eea42a1afb01dd44110582f997115b50e742François Gaffie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
219368eea42a1afb01dd44110582f997115b50e742François Gaffie * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
229368eea42a1afb01dd44110582f997115b50e742François Gaffie * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
239368eea42a1afb01dd44110582f997115b50e742François Gaffie * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
249368eea42a1afb01dd44110582f997115b50e742François Gaffie * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
259368eea42a1afb01dd44110582f997115b50e742François Gaffie * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
269368eea42a1afb01dd44110582f997115b50e742François Gaffie * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
279368eea42a1afb01dd44110582f997115b50e742François Gaffie * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
289368eea42a1afb01dd44110582f997115b50e742François Gaffie * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
299368eea42a1afb01dd44110582f997115b50e742François Gaffie */
309368eea42a1afb01dd44110582f997115b50e742François Gaffie
319368eea42a1afb01dd44110582f997115b50e742François Gaffie#include "Utility.h"
329368eea42a1afb01dd44110582f997115b50e742François Gaffie#include "BinaryCopy.hpp"
339368eea42a1afb01dd44110582f997115b50e742François Gaffie
349368eea42a1afb01dd44110582f997115b50e742François Gaffie#include <catch.hpp>
359368eea42a1afb01dd44110582f997115b50e742François Gaffie#include <functional>
369368eea42a1afb01dd44110582f997115b50e742François Gaffie#include <map>
379368eea42a1afb01dd44110582f997115b50e742François Gaffie
389368eea42a1afb01dd44110582f997115b50e742François Gaffieusing std::list;
399368eea42a1afb01dd44110582f997115b50e742François Gaffieusing std::string;
409368eea42a1afb01dd44110582f997115b50e742François Gaffie
419368eea42a1afb01dd44110582f997115b50e742François Gaffienamespace utility
429368eea42a1afb01dd44110582f997115b50e742François Gaffie{
439368eea42a1afb01dd44110582f997115b50e742François Gaffie
449368eea42a1afb01dd44110582f997115b50e742François GaffieSCENARIO("join<int>")
459368eea42a1afb01dd44110582f997115b50e742François Gaffie{
469368eea42a1afb01dd44110582f997115b50e742François Gaffie    struct Test
479368eea42a1afb01dd44110582f997115b50e742François Gaffie    {
489368eea42a1afb01dd44110582f997115b50e742François Gaffie        list<int> input;
499368eea42a1afb01dd44110582f997115b50e742François Gaffie        std::function<int(int, int)> binaryOpt;
509368eea42a1afb01dd44110582f997115b50e742François Gaffie        int empty;
519368eea42a1afb01dd44110582f997115b50e742François Gaffie        int result;
529368eea42a1afb01dd44110582f997115b50e742François Gaffie        int resultNoEmpty;
539368eea42a1afb01dd44110582f997115b50e742François Gaffie    };
549368eea42a1afb01dd44110582f997115b50e742François Gaffie    const list<Test> tests = {{{}, nullptr, 21, 21, 0},
559368eea42a1afb01dd44110582f997115b50e742François Gaffie                              {{5}, nullptr, -1, 5, 5},
569368eea42a1afb01dd44110582f997115b50e742François Gaffie                              {{5, 2}, [](int, int) { return 73; }, -1, 73, 73},
579368eea42a1afb01dd44110582f997115b50e742François Gaffie                              {{2, 3, 7}, [](int l, int r) { return l * r; }, -1, 42, 42},
589368eea42a1afb01dd44110582f997115b50e742François Gaffie                              {{1, 10, 100}, [](int l, int r) { return l + r; }, -1, 111, 111}};
599368eea42a1afb01dd44110582f997115b50e742François Gaffie    for (auto &test : tests) {
609368eea42a1afb01dd44110582f997115b50e742François Gaffie        CAPTURE(Catch::toString(test.input));
619368eea42a1afb01dd44110582f997115b50e742François Gaffie        const auto &first = begin(test.input);
629368eea42a1afb01dd44110582f997115b50e742François Gaffie        const auto &last = end(test.input);
639368eea42a1afb01dd44110582f997115b50e742François Gaffie        REQUIRE(join(first, last, test.binaryOpt, test.empty) == test.result);
649368eea42a1afb01dd44110582f997115b50e742François Gaffie        REQUIRE(join<int>(first, last, test.binaryOpt) == test.resultNoEmpty);
659368eea42a1afb01dd44110582f997115b50e742François Gaffie    }
669368eea42a1afb01dd44110582f997115b50e742François Gaffie}
679368eea42a1afb01dd44110582f997115b50e742François Gaffie
689368eea42a1afb01dd44110582f997115b50e742François GaffieSCENARIO("asString(list)")
699368eea42a1afb01dd44110582f997115b50e742François Gaffie{
709368eea42a1afb01dd44110582f997115b50e742François Gaffie    struct Test
719368eea42a1afb01dd44110582f997115b50e742François Gaffie    {
729368eea42a1afb01dd44110582f997115b50e742François Gaffie        string title;
739368eea42a1afb01dd44110582f997115b50e742François Gaffie        list<string> input;
749368eea42a1afb01dd44110582f997115b50e742François Gaffie        string separator;
759368eea42a1afb01dd44110582f997115b50e742François Gaffie        string result;
769368eea42a1afb01dd44110582f997115b50e742François Gaffie        string resultNoSep;
779368eea42a1afb01dd44110582f997115b50e742François Gaffie    };
789368eea42a1afb01dd44110582f997115b50e742François Gaffie    const list<Test> tests = {
799368eea42a1afb01dd44110582f997115b50e742François Gaffie        {"Empty list", {}, "aa", "", ""},
809368eea42a1afb01dd44110582f997115b50e742François Gaffie        {"One element", {"a"}, "<>", "a", "a"},
819368eea42a1afb01dd44110582f997115b50e742François Gaffie        {"Three elem list", {"1", "2", "3"}, "**", "1**2**3", "1\n2\n3"},
829368eea42a1afb01dd44110582f997115b50e742François Gaffie        {"No separator", {"12", "ab", "+-"}, "", "12ab+-", "12\nab\n+-"},
839368eea42a1afb01dd44110582f997115b50e742François Gaffie        {"empty elem list", {"a", "b", "", "d"}, "|", "a|b||d", "a\nb\n\nd"},
849368eea42a1afb01dd44110582f997115b50e742François Gaffie    };
859368eea42a1afb01dd44110582f997115b50e742François Gaffie    for (auto &test : tests) {
869368eea42a1afb01dd44110582f997115b50e742François Gaffie        CAPTURE(Catch::toString(test.input));
879368eea42a1afb01dd44110582f997115b50e742François Gaffie        WHEN ("Separator, " + test.title) {
889368eea42a1afb01dd44110582f997115b50e742François Gaffie            CAPTURE(test.separator);
899368eea42a1afb01dd44110582f997115b50e742François Gaffie            REQUIRE(asString(test.input, test.separator) == test.result);
909368eea42a1afb01dd44110582f997115b50e742François Gaffie        }
919368eea42a1afb01dd44110582f997115b50e742François Gaffie        THEN ("No separator, " + test.title) {
929368eea42a1afb01dd44110582f997115b50e742François Gaffie            REQUIRE(asString(test.input) == test.resultNoSep);
939368eea42a1afb01dd44110582f997115b50e742François Gaffie        }
949368eea42a1afb01dd44110582f997115b50e742François Gaffie    }
959368eea42a1afb01dd44110582f997115b50e742François Gaffie}
969368eea42a1afb01dd44110582f997115b50e742François Gaffie
979368eea42a1afb01dd44110582f997115b50e742François GaffieSCENARIO("asString(map)")
989368eea42a1afb01dd44110582f997115b50e742François Gaffie{
999368eea42a1afb01dd44110582f997115b50e742François Gaffie    using std::map;
1009368eea42a1afb01dd44110582f997115b50e742François Gaffie
1019368eea42a1afb01dd44110582f997115b50e742François Gaffie    using Map = map<string, string>;
1029368eea42a1afb01dd44110582f997115b50e742François Gaffie    struct Test
1039368eea42a1afb01dd44110582f997115b50e742François Gaffie    {
1049368eea42a1afb01dd44110582f997115b50e742François Gaffie        Map input;
1059368eea42a1afb01dd44110582f997115b50e742François Gaffie        string itemSep;
1069368eea42a1afb01dd44110582f997115b50e742François Gaffie        string keyValueSep;
1079368eea42a1afb01dd44110582f997115b50e742François Gaffie        string result;
1089368eea42a1afb01dd44110582f997115b50e742François Gaffie        string resultNoKeyValueSep;
1099368eea42a1afb01dd44110582f997115b50e742François Gaffie        string resultNoSep;
1109368eea42a1afb01dd44110582f997115b50e742François Gaffie    };
1119368eea42a1afb01dd44110582f997115b50e742François Gaffie    const list<Test> tests = {{{}, "itemSep", "keyValueSep", "", "", ""},
1129368eea42a1afb01dd44110582f997115b50e742François Gaffie                              {
1139368eea42a1afb01dd44110582f997115b50e742François Gaffie                                  Map{{"a", "b"}, {"c", "d"}, {"e", "f"}}, // input
1149368eea42a1afb01dd44110582f997115b50e742François Gaffie                                  " - ", "\n",                             // item & keyValue sep
1159368eea42a1afb01dd44110582f997115b50e742François Gaffie                                  "a - b\nc - d\ne - f",                   // result
1169368eea42a1afb01dd44110582f997115b50e742François Gaffie                                  "a:b\nc:d\ne:f",                         // resultNoKeyValueSep
1179368eea42a1afb01dd44110582f997115b50e742François Gaffie                                  "a:b, c:d, e:f"                          // resultNoSep
1189368eea42a1afb01dd44110582f997115b50e742François Gaffie                              }};
1199368eea42a1afb01dd44110582f997115b50e742François Gaffie    for (const auto &test : tests) {
1209368eea42a1afb01dd44110582f997115b50e742François Gaffie        CAPTURE(Catch::toString(test.input));
1219368eea42a1afb01dd44110582f997115b50e742François Gaffie        CAPTURE(test.keyValueSep);
1229368eea42a1afb01dd44110582f997115b50e742François Gaffie        CAPTURE(test.itemSep);
1239368eea42a1afb01dd44110582f997115b50e742François Gaffie        REQUIRE(asString(test.input, test.keyValueSep, test.itemSep) == test.result);
1249368eea42a1afb01dd44110582f997115b50e742François Gaffie        REQUIRE(asString(test.input, test.keyValueSep) == test.resultNoKeyValueSep);
1259368eea42a1afb01dd44110582f997115b50e742François Gaffie        REQUIRE(asString(test.input) == test.resultNoSep);
1269368eea42a1afb01dd44110582f997115b50e742François Gaffie    }
1279368eea42a1afb01dd44110582f997115b50e742François Gaffie}
1289368eea42a1afb01dd44110582f997115b50e742François Gaffie
1299368eea42a1afb01dd44110582f997115b50e742François GaffieSCENARIO("appendTitle")
1309368eea42a1afb01dd44110582f997115b50e742François Gaffie{
1319368eea42a1afb01dd44110582f997115b50e742François Gaffie    struct Test
1329368eea42a1afb01dd44110582f997115b50e742François Gaffie    {
1339368eea42a1afb01dd44110582f997115b50e742François Gaffie        string initial;
1349368eea42a1afb01dd44110582f997115b50e742François Gaffie        string title;
1359368eea42a1afb01dd44110582f997115b50e742François Gaffie        string result;
1369368eea42a1afb01dd44110582f997115b50e742François Gaffie    };
1379368eea42a1afb01dd44110582f997115b50e742François Gaffie    const list<Test> tests = {{"", "abc", "\nabc\n===\n"},
1389368eea42a1afb01dd44110582f997115b50e742François Gaffie                              {"start", "title", "start\ntitle\n=====\n"}};
1399368eea42a1afb01dd44110582f997115b50e742François Gaffie    for (auto &test : tests) {
1409368eea42a1afb01dd44110582f997115b50e742François Gaffie        auto quote = [](std::string toQuote) { return '"' + toQuote + '"'; };
1419368eea42a1afb01dd44110582f997115b50e742François Gaffie
1429368eea42a1afb01dd44110582f997115b50e742François Gaffie        GIVEN ("A title: " + quote(test.title)) {
1439368eea42a1afb01dd44110582f997115b50e742François Gaffie            CAPTURE(test.initial);
1449368eea42a1afb01dd44110582f997115b50e742François Gaffie            CAPTURE(test.title);
1459368eea42a1afb01dd44110582f997115b50e742François Gaffie
1469368eea42a1afb01dd44110582f997115b50e742François Gaffie            WHEN ("Appending to: " + quote(test.initial)) {
1479368eea42a1afb01dd44110582f997115b50e742François Gaffie                string output = test.initial;
1489368eea42a1afb01dd44110582f997115b50e742François Gaffie                THEN ("Result should be:\n" + quote(test.result)) {
1499368eea42a1afb01dd44110582f997115b50e742François Gaffie                    appendTitle(output, test.title);
1509368eea42a1afb01dd44110582f997115b50e742François Gaffie                    CHECK(output == test.result);
1519368eea42a1afb01dd44110582f997115b50e742François Gaffie                }
1529368eea42a1afb01dd44110582f997115b50e742François Gaffie            }
1539368eea42a1afb01dd44110582f997115b50e742François Gaffie        }
1549368eea42a1afb01dd44110582f997115b50e742François Gaffie    }
1559368eea42a1afb01dd44110582f997115b50e742François Gaffie}
1569368eea42a1afb01dd44110582f997115b50e742François Gaffie
1579368eea42a1afb01dd44110582f997115b50e742François GaffieSCENARIO("isNotHexadecimal")
1589368eea42a1afb01dd44110582f997115b50e742François Gaffie{
1599368eea42a1afb01dd44110582f997115b50e742François Gaffie    for (auto &str : {"a", "0", "012", "13", "ABC", "Oxa"}) {
1609368eea42a1afb01dd44110582f997115b50e742François Gaffie        CAPTURE(str);
1619368eea42a1afb01dd44110582f997115b50e742François Gaffie        CHECK(not isHexadecimal(str));
1629368eea42a1afb01dd44110582f997115b50e742François Gaffie    }
1639368eea42a1afb01dd44110582f997115b50e742François Gaffie}
1649368eea42a1afb01dd44110582f997115b50e742François Gaffie
1659368eea42a1afb01dd44110582f997115b50e742François GaffieSCENARIO("isHexadecimal")
1669368eea42a1afb01dd44110582f997115b50e742François Gaffie{
1679368eea42a1afb01dd44110582f997115b50e742François Gaffie    for (auto str : {"0xa", "0X0", "0x012", "0x13", "0xConsider as hexa as starting with 0x"}) {
1689368eea42a1afb01dd44110582f997115b50e742François Gaffie        CAPTURE(str);
1699368eea42a1afb01dd44110582f997115b50e742François Gaffie        CHECK(isHexadecimal(str));
1709368eea42a1afb01dd44110582f997115b50e742François Gaffie    }
1719368eea42a1afb01dd44110582f997115b50e742François Gaffie}
1729368eea42a1afb01dd44110582f997115b50e742François Gaffie
1739368eea42a1afb01dd44110582f997115b50e742François Gaffietemplate <class T1, class T2>
1749368eea42a1afb01dd44110582f997115b50e742François Gaffievoid checkBinaryEqual(T1 v1, T2 v2)
1759368eea42a1afb01dd44110582f997115b50e742François Gaffie{
1769368eea42a1afb01dd44110582f997115b50e742François Gaffie    // For some yet-unknown reason, GCC 4.8 complains about
1779368eea42a1afb01dd44110582f997115b50e742François Gaffie    //     CHECK(a == b);
1789368eea42a1afb01dd44110582f997115b50e742François Gaffie    // and suggests that parentheses should be added. This is related to catch
1799368eea42a1afb01dd44110582f997115b50e742François Gaffie    // internals but such construcuts have been used without problem in lots of
1809368eea42a1afb01dd44110582f997115b50e742François Gaffie    // other places...
1819368eea42a1afb01dd44110582f997115b50e742François Gaffie    // Besides, GCC 4.9 does not seem to have a problem with that either.
1829368eea42a1afb01dd44110582f997115b50e742François Gaffie    // As a workaround, captures variables and parenthesize the expressions.
1839368eea42a1afb01dd44110582f997115b50e742François Gaffie
1849368eea42a1afb01dd44110582f997115b50e742François Gaffie    auto v2AsT1 = utility::binaryCopy<T1>(v2);
1859368eea42a1afb01dd44110582f997115b50e742François Gaffie    CAPTURE(v1);
1869368eea42a1afb01dd44110582f997115b50e742François Gaffie    CAPTURE(v2AsT1);
1879368eea42a1afb01dd44110582f997115b50e742François Gaffie    CHECK((v1 == v2AsT1));
1889368eea42a1afb01dd44110582f997115b50e742François Gaffie
1899368eea42a1afb01dd44110582f997115b50e742François Gaffie    auto v1AsT2 = utility::binaryCopy<T2>(v1);
1909368eea42a1afb01dd44110582f997115b50e742François Gaffie    CAPTURE(v2);
1919368eea42a1afb01dd44110582f997115b50e742François Gaffie    CAPTURE(v1AsT2);
1929368eea42a1afb01dd44110582f997115b50e742François Gaffie    CHECK((v2 == v1AsT2));
1939368eea42a1afb01dd44110582f997115b50e742François Gaffie}
1949368eea42a1afb01dd44110582f997115b50e742François Gaffie
1959368eea42a1afb01dd44110582f997115b50e742François GaffieSCENARIO("binaryCopy bit exactness")
1969368eea42a1afb01dd44110582f997115b50e742François Gaffie{
1979368eea42a1afb01dd44110582f997115b50e742François Gaffie    GIVEN ("Integer representations computed using http://babbage.cs.qc.cuny.edu/IEEE-754/") {
1989368eea42a1afb01dd44110582f997115b50e742François Gaffie
1999368eea42a1afb01dd44110582f997115b50e742François Gaffie        THEN ("Floats should be coded on 32bits and fulfill IEEE-754."
2009368eea42a1afb01dd44110582f997115b50e742François Gaffie              " That assumption is made in the Parameter Framework.") {
2019368eea42a1afb01dd44110582f997115b50e742François Gaffie            REQUIRE(sizeof(float) == sizeof(uint32_t));
2029368eea42a1afb01dd44110582f997115b50e742François Gaffie            REQUIRE(std::numeric_limits<float>::is_iec559);
2039368eea42a1afb01dd44110582f997115b50e742François Gaffie        }
2049368eea42a1afb01dd44110582f997115b50e742François Gaffie        WHEN ("Testing float <=> uint32_t conversion") {
2059368eea42a1afb01dd44110582f997115b50e742François Gaffie            checkBinaryEqual<float, uint32_t>(1.23456f, 0x3f9e0610);
2069368eea42a1afb01dd44110582f997115b50e742François Gaffie        }
2079368eea42a1afb01dd44110582f997115b50e742François Gaffie
2089368eea42a1afb01dd44110582f997115b50e742François Gaffie        THEN ("Doubles should be coded on 64bits and fulfill IEEE-754."
2099368eea42a1afb01dd44110582f997115b50e742François Gaffie              " That assumption is made in the Parameter Framework.") {
2109368eea42a1afb01dd44110582f997115b50e742François Gaffie            REQUIRE(sizeof(double) == sizeof(uint64_t));
2119368eea42a1afb01dd44110582f997115b50e742François Gaffie            REQUIRE(std::numeric_limits<double>::is_iec559);
2129368eea42a1afb01dd44110582f997115b50e742François Gaffie        }
2139368eea42a1afb01dd44110582f997115b50e742François Gaffie        WHEN ("Testing double <=> uint64_t conversion") {
2149368eea42a1afb01dd44110582f997115b50e742François Gaffie            checkBinaryEqual<double, uint64_t>(987.65432109876, 0x408edd3c0cb3420e);
2159368eea42a1afb01dd44110582f997115b50e742François Gaffie        }
2169368eea42a1afb01dd44110582f997115b50e742François Gaffie    }
2179368eea42a1afb01dd44110582f997115b50e742François Gaffie
2189368eea42a1afb01dd44110582f997115b50e742François Gaffie    WHEN ("Testing int8_t <=> uint8_t conversion") {
2199368eea42a1afb01dd44110582f997115b50e742François Gaffie        checkBinaryEqual<int8_t, uint8_t>(-1, 0xff);
2209368eea42a1afb01dd44110582f997115b50e742François Gaffie    }
2219368eea42a1afb01dd44110582f997115b50e742François Gaffie}
2229368eea42a1afb01dd44110582f997115b50e742François Gaffie
2239368eea42a1afb01dd44110582f997115b50e742François Gaffie} // namespace utility
224