<commit_before>/* -------------------------------------------------------------------------- *
 *                            OpenSim:  testTRCFileAdapter.cpp                *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2017 Stanford University and the Authors                *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

#include "OpenSim/Common/Adapters.h"
#include <OpenSim/Common/IO.h>

#include <fstream>
#include <cstdio>

void testFailed(const std::string& filename,
                const std::string& origtoken,
                const std::string& copiedtoken) {
    using namespace OpenSim;

    throw Exception{"Test failed: Original and copied TRC files do not match. "
            "Filename = '" + filename + "'. "
            "Expected token = " + origtoken + ". "
            "Copied token = " + copiedtoken + "."};
}

void compareFiles(const std::string& filenameA,
                  const std::string& filenameB) {
    // Delimiters include carriage return and newline.
    const std::string delims{"\t\r\n"};

    std::ifstream fileA{filenameA};
    std::ifstream fileB{filenameB};

    int lcnt = 0;

    while (fileA && fileB) {
        auto tokensA = OpenSim::FileAdapter::getNextLine(fileA, delims);
        auto tokensB = OpenSim::FileAdapter::getNextLine(fileB, delims);

        ++lcnt;

        if (tokensA.size() != tokensB.size() && lcnt < 6) {
            // original could have any number of tabs and spaces
            // that are no longer allowed. So ignore them.
            OpenSim::IO::eraseEmptyElements(tokensA);
            OpenSim::IO::eraseEmptyElements(tokensB);
        }

        if (tokensA.size() != tokensB.size()) {
            //if a blank row, skip it
            if (tokensA.empty() || tokensA.at(0).empty()) {
                tokensA = OpenSim::FileAdapter::getNextLine(fileA, delims);
                ++lcnt;
            }
            if (tokensB.empty() || tokensB.at(0).empty()) {
                tokensB = OpenSim::FileAdapter::getNextLine(fileB, delims);
                ++lcnt;
            }
        }

        std::string msg{ "Number of elements at line " +
            std::to_string(lcnt) + " did not match." };

        OPENSIM_THROW_IF(tokensA.size() != tokensB.size(),
            OpenSim::Exception, msg);

        for (size_t i = 0; i < tokensA.size(); ++i) {
            if (tokensA[i] == tokensB[i]) {
                continue;
            }
            std::string tokenA{ tokensA[i] };
            std::string tokenB{ tokensB[i] };
            OpenSim::IO::TrimWhitespace(tokenA);
            OpenSim::IO::TrimWhitespace(tokenB);
            tokenA = OpenSim::IO::Lowercase(tokenA);
            tokenB = OpenSim::IO::Lowercase(tokenB);
            if (tokenA == tokenB) {
                continue;
            }
            // We interpreted blank as NaN now revert
            // to compare to the original file with blanks
            if (tokenB == "nan") {
                tokenB = "";
            }
            else if (tokenA == "nan") {
                tokenA = "";
            }
            if (tokenA == tokenB) {
                continue;
            }
            double d_tokenA{};
            double d_tokenB{};
            try {
                d_tokenA = std::stod(tokenA);
                d_tokenB = std::stod(tokenB);
            }
            catch (std::invalid_argument&) {
                testFailed(filenameA, tokenA, tokenB);
            }
            if ((d_tokenA != d_tokenB) &&
                !(std::isnan(d_tokenA) &&
                    std::isnan(d_tokenB))) {
                testFailed(filenameA, tokenA, tokenB);
            }
        } // end for
    } // end while
}

int main() {
    using namespace OpenSim;

    std::vector<std::string> filenames{};
    filenames.push_back("dataWithEformat.trc");
    filenames.push_back("dataWithNaNsOfDifferentCases.trc");
    filenames.push_back("dataWithNaNsWithSpaces.trc");
    filenames.push_back("dataWithBlanksForMissingMarkers.trc");
    filenames.push_back("exampleFormat.trc");
    // TRCs that are shared with other tests
    filenames.push_back("subject01_synthetic_marker_data.trc");
    filenames.push_back("constraintTest.trc");
    filenames.push_back("subject01_static.trc");
    filenames.push_back("gait10dof18musc_walk_CRLF_line_ending.trc");

    std::string tmpfile{"testtrcfileadapter.trc"};

    bool failed = false;

    std::cout << "Testing TRCFileAdapter::read() and TRCFileAdapter::write()"
              << std::endl;
    for(const auto& filename : filenames) {
        std::cout << "  " << filename << std::endl;
        TRCFileAdapter trcfileadapter{};
        try {
            auto table = trcfileadapter.read(filename);
            trcfileadapter.write(table, tmpfile);
            compareFiles(filename, tmpfile);
        }
        catch (std::exception& ex) {
            std::cout << "Failed because: '" << ex.what() << "'." << std::endl;
            failed = true;
        }
    }

    std::cout << "Testing FileAdapter::readFile() and FileAdapter::writeFile()"
              << std::endl;
    for(const auto& filename : filenames) {
        std::cout << "  " << filename << std::endl;
        try {
            auto table = FileAdapter::readFile(filename).at("markers");
            DataAdapter::InputTables tables{};
            tables.emplace(std::string{ "markers" }, table.get());
            FileAdapter::writeFile(tables, tmpfile);
            compareFiles(filename, tmpfile);
        }
        catch (std::exception& ex) {
            std::cout << "Failed because: '" << ex.what() << "'." << std::endl;
            failed = true;
        }
    }

    std::cout << "Testing TimeSeriesTableVec3 and TRCFileAdapter::write()"
              << std::endl;
    for(const auto& filename : filenames) {
        try {
            std::cout << "  " << filename << std::endl;
            TimeSeriesTableVec3 table{filename};
            TRCFileAdapter::write(table, tmpfile);
            compareFiles(filename, tmpfile);
        }
        catch (std::exception& ex) {
            std::cout << "Failed because: '" << ex.what() << "'." << std::endl;
            failed = true;
        }
    }

    if (failed)
        return 1;

    std::remove(tmpfile.c_str());
    std::cout << "\nAll tests passed!" << std::endl;

    return 0;
}
<commit_msg>Specify numberOfTRCHeaderLines in test.<commit_after>/* -------------------------------------------------------------------------- *
 *                            OpenSim:  testTRCFileAdapter.cpp                *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2017 Stanford University and the Authors                *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

#include "OpenSim/Common/Adapters.h"
#include <OpenSim/Common/IO.h>

#include <fstream>
#include <cstdio>

void testFailed(const std::string& filename,
                const std::string& origtoken,
                const std::string& copiedtoken) {
    using namespace OpenSim;

    throw Exception{"Test failed: Original and copied TRC files do not match. "
            "Filename = '" + filename + "'. "
            "Expected token = " + origtoken + ". "
            "Copied token = " + copiedtoken + "."};
}

void compareFiles(const std::string& filenameA,
                  const std::string& filenameB) {
    // Delimiters include carriage return and newline.
    const std::string delims{"\t\r\n"};

    std::ifstream fileA{filenameA};
    std::ifstream fileB{filenameB};

    const size_t numOfTRCHeaderLines = 6;

    size_t lcnt = 0;

    while (fileA && fileB) {
        auto tokensA = OpenSim::FileAdapter::getNextLine(fileA, delims);
        auto tokensB = OpenSim::FileAdapter::getNextLine(fileB, delims);

        ++lcnt;

        if (tokensA.size() != tokensB.size() && lcnt < numOfTRCHeaderLines) {
            // original could have any number of tabs and spaces
            // that are no longer allowed. So ignore them.
            OpenSim::IO::eraseEmptyElements(tokensA);
            OpenSim::IO::eraseEmptyElements(tokensB);
        }

        if (tokensA.size() != tokensB.size()) {
            //if a blank row, skip it
            if (tokensA.empty() || tokensA.at(0).empty()) {
                tokensA = OpenSim::FileAdapter::getNextLine(fileA, delims);
                ++lcnt;
            }
            if (tokensB.empty() || tokensB.at(0).empty()) {
                tokensB = OpenSim::FileAdapter::getNextLine(fileB, delims);
                ++lcnt;
            }
        }

        std::string msg{ "Number of elements at line " +
            std::to_string(lcnt) + " did not match." };

        OPENSIM_THROW_IF(tokensA.size() != tokensB.size(),
            OpenSim::Exception, msg);

        for (size_t i = 0; i < tokensA.size(); ++i) {
            if (tokensA[i] == tokensB[i]) {
                continue;
            }
            std::string tokenA{ tokensA[i] };
            std::string tokenB{ tokensB[i] };
            OpenSim::IO::TrimWhitespace(tokenA);
            OpenSim::IO::TrimWhitespace(tokenB);
            tokenA = OpenSim::IO::Lowercase(tokenA);
            tokenB = OpenSim::IO::Lowercase(tokenB);
            if (tokenA == tokenB) {
                continue;
            }
            // We interpreted blank as NaN now revert
            // to compare to the original file with blanks
            if (tokenB == "nan") {
                tokenB = "";
            }
            else if (tokenA == "nan") {
                tokenA = "";
            }
            if (tokenA == tokenB) {
                continue;
            }
            double d_tokenA{};
            double d_tokenB{};
            try {
                d_tokenA = std::stod(tokenA);
                d_tokenB = std::stod(tokenB);
            }
            catch (std::invalid_argument&) {
                testFailed(filenameA, tokenA, tokenB);
            }
            if ((d_tokenA != d_tokenB) &&
                !(std::isnan(d_tokenA) &&
                    std::isnan(d_tokenB))) {
                testFailed(filenameA, tokenA, tokenB);
            }
        } // end for
    } // end while
}

int main() {
    using namespace OpenSim;

    std::vector<std::string> filenames{};
    filenames.push_back("dataWithEformat.trc");
    filenames.push_back("dataWithNaNsOfDifferentCases.trc");
    filenames.push_back("dataWithNaNsWithSpaces.trc");
    filenames.push_back("dataWithBlanksForMissingMarkers.trc");
    filenames.push_back("exampleFormat.trc");
    // TRCs that are shared with other tests
    filenames.push_back("subject01_synthetic_marker_data.trc");
    filenames.push_back("constraintTest.trc");
    filenames.push_back("subject01_static.trc");
    filenames.push_back("gait10dof18musc_walk_CRLF_line_ending.trc");

    std::string tmpfile{"testtrcfileadapter.trc"};

    bool failed = false;

    std::cout << "Testing TRCFileAdapter::read() and TRCFileAdapter::write()"
              << std::endl;
    for(const auto& filename : filenames) {
        std::cout << "  " << filename << std::endl;
        TRCFileAdapter trcfileadapter{};
        try {
            auto table = trcfileadapter.read(filename);
            trcfileadapter.write(table, tmpfile);
            compareFiles(filename, tmpfile);
        }
        catch (std::exception& ex) {
            std::cout << "Failed because: '" << ex.what() << "'." << std::endl;
            failed = true;
        }
    }

    std::cout << "Testing FileAdapter::readFile() and FileAdapter::writeFile()"
              << std::endl;
    for(const auto& filename : filenames) {
        std::cout << "  " << filename << std::endl;
        try {
            auto table = FileAdapter::readFile(filename).at("markers");
            DataAdapter::InputTables tables{};
            tables.emplace(std::string{ "markers" }, table.get());
            FileAdapter::writeFile(tables, tmpfile);
            compareFiles(filename, tmpfile);
        }
        catch (std::exception& ex) {
            std::cout << "Failed because: '" << ex.what() << "'." << std::endl;
            failed = true;
        }
    }

    std::cout << "Testing TimeSeriesTableVec3 and TRCFileAdapter::write()"
              << std::endl;
    for(const auto& filename : filenames) {
        try {
            std::cout << "  " << filename << std::endl;
            TimeSeriesTableVec3 table{filename};
            TRCFileAdapter::write(table, tmpfile);
            compareFiles(filename, tmpfile);
        }
        catch (std::exception& ex) {
            std::cout << "Failed because: '" << ex.what() << "'." << std::endl;
            failed = true;
        }
    }

    if (failed)
        return 1;

    std::remove(tmpfile.c_str());
    std::cout << "\nAll tests passed!" << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>#include "cpp_redis/redis_client.hpp"
#include "cpp_redis/redis_error.hpp"

namespace cpp_redis {

redis_client::~redis_client(void) {
  if (is_connected())
    disconnect();
}

void
redis_client::connect(const std::string& host, unsigned int port,
                      const disconnection_handler_t& client_disconnection_handler)
{
  m_disconnection_handler = client_disconnection_handler;

  auto disconnection_handler = std::bind(&redis_client::connection_disconnection_handler, this, std::placeholders::_1);
  auto receive_handler = std::bind(&redis_client::connection_receive_handler, this, std::placeholders::_1, std::placeholders::_2);
  m_client.connect(host, port, disconnection_handler, receive_handler);
}

void
redis_client::disconnect(void) {
  m_client.disconnect();
}

bool
redis_client::is_connected(void) {
  return m_client.is_connected();
}

void
redis_client::send(const std::vector<std::string>& redis_cmd, const reply_callback_t& callback) {
  std::lock_guard<std::mutex> lock(m_callbacks_mutex);

  m_client.send(redis_cmd);
  m_callbacks.push(callback);
}

void
redis_client::connection_receive_handler(network::redis_connection&, reply& reply) {
  std::lock_guard<std::mutex> lock(m_callbacks_mutex);

  if (not m_callbacks.size())
    return ;

  if (m_callbacks.front())
    m_callbacks.front()(reply);

  m_callbacks.pop();
}

void
redis_client::clear_callbacks(void) {
  std::lock_guard<std::mutex> lock(m_callbacks_mutex);

  std::queue<reply_callback_t> empty;
  std::swap(m_callbacks, empty);
}

void
redis_client::call_disconnection_handler(void) {
  if (m_disconnection_handler)
    m_disconnection_handler(*this);
}

void
redis_client::connection_disconnection_handler(network::redis_connection&) {
  clear_callbacks();
  call_disconnection_handler();
}

} //! cpp_redis
<commit_msg>patch deadlock in the redis_client when sending command. Origin was deep, due to interleaved locks between redis_command & io_service through callbacks.<commit_after>#include "cpp_redis/redis_client.hpp"
#include "cpp_redis/redis_error.hpp"

namespace cpp_redis {

redis_client::~redis_client(void) {
  if (is_connected())
    disconnect();
}

void
redis_client::connect(const std::string& host, unsigned int port,
                      const disconnection_handler_t& client_disconnection_handler)
{
  m_disconnection_handler = client_disconnection_handler;

  auto disconnection_handler = std::bind(&redis_client::connection_disconnection_handler, this, std::placeholders::_1);
  auto receive_handler = std::bind(&redis_client::connection_receive_handler, this, std::placeholders::_1, std::placeholders::_2);
  m_client.connect(host, port, disconnection_handler, receive_handler);
}

void
redis_client::disconnect(void) {
  m_client.disconnect();
}

bool
redis_client::is_connected(void) {
  return m_client.is_connected();
}

void
redis_client::send(const std::vector<std::string>& redis_cmd, const reply_callback_t& callback) {
  m_client.send(redis_cmd);

  std::lock_guard<std::mutex> lock(m_callbacks_mutex);
  m_callbacks.push(callback);
}

void
redis_client::connection_receive_handler(network::redis_connection&, reply& reply) {
  std::lock_guard<std::mutex> lock(m_callbacks_mutex);

  if (not m_callbacks.size())
    return ;

  if (m_callbacks.front())
    m_callbacks.front()(reply);

  m_callbacks.pop();
}

void
redis_client::clear_callbacks(void) {
  std::lock_guard<std::mutex> lock(m_callbacks_mutex);

  std::queue<reply_callback_t> empty;
  std::swap(m_callbacks, empty);
}

void
redis_client::call_disconnection_handler(void) {
  if (m_disconnection_handler)
    m_disconnection_handler(*this);
}

void
redis_client::connection_disconnection_handler(network::redis_connection&) {
  clear_callbacks();
  call_disconnection_handler();
}

} //! cpp_redis
<|endoftext|>


<commit_before>#pragma once

#include <cstddef>
#include <iostream>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

namespace Traits
{
   /**
   * @brief P.F.M
   *
   * @see N3911
   */
   template<class...>
   using void_t = void;

   /**
   * @brief Base case for the testing of STD compatible container types.
   */
   template<
      typename /*Type*/,
      typename = void
   >
   struct is_printable_as_container : std::false_type
   {
   };

   /**
   * @brief Specialization to ensure that Standard Library compatible containers that have
   * `begin()`, `end()`, and `empty()` member functions, as well as the `value_type` and
   * `iterator` typedefs, are treated as printable containers.
   */
   template<typename Type>
   struct is_printable_as_container<
      Type,
      void_t<
         decltype(std::declval<Type&>().begin()),
         decltype(std::declval<Type&>().end()),
         decltype(std::declval<Type&>().empty()),
         typename Type::value_type,
         typename Type::iterator
      >
   > : public std::true_type
   {
   };

   /**
   * @brief Specialization to treat std::pair<...> as a printable container type.
   */
   template<
      typename FirstType,
      typename SecondType
   >
   struct is_printable_as_container<std::pair<FirstType, SecondType>> : public std::true_type
   {
   };

   /**
   * @brief Specialization to treat std::tuple<...> as a printable container type.
   */
   template<typename... DataTypes>
   struct is_printable_as_container<std::tuple<DataTypes...>> : public std::true_type
   {
   };

   /**
   * @brief Specialization to treat arrays as printable container types.
   */
   template<
      typename ArrayType,
      std::size_t ArraySize
   >
   struct is_printable_as_container<ArrayType[ArraySize]> : public std::true_type
   {
   };

   /**
   * @brief Narrow character array specialization in order to ensure that we print character arrays
   * as string and not as delimiter containers.
   */
   template<std::size_t ArraySize>
   struct is_printable_as_container<char[ArraySize]> : public std::false_type
   {
   };

   /**
   * @brief Wide character array specialization in order to ensure that we print character arrays
   * as string and not as delimiter containers.
   */
   template<std::size_t ArraySize>
   struct is_printable_as_container<wchar_t[ArraySize]> : public std::false_type
   {
   };

   /**
   * @brief String specialization in order to ensure that we treat strings as nothing more than strings.
   */
   template<
      typename CharacterType,
      typename TraitsType,
      typename AllocatorType
   >
   struct is_printable_as_container<
      std::basic_string<
      CharacterType,
         TraitsType,
         AllocatorType
      >
   > : public std::false_type
   {
   };

   /**
   * @brief Helper variable template.
   */
   template<typename Type>
   constexpr bool is_printable_as_container_v = is_printable_as_container<Type>::value;
}

namespace Printer
{
   /**
   * @brief Struct to neatly wrap up all the additional characters we'll need in order to
   * print out the containers.
   */
   template<typename DelimiterType>
   struct delimiter_values
   {
      using type = DelimiterType;

      const type* prefix;
      const type* separator;
      const type* suffix;
   };

   /**
   * @brief Additional wrapper around the `delimiter_values` struct for added convenience.
   */
   template<
      typename /*ContainerType*/,
      typename DelimiterType
   >
   struct delimiters
   {
      using type = delimiter_values<DelimiterType>;

      static const type values;
   };

   /**
   * @brief Default narrow delimiters for any container type that isn't specialized.
   */
   template<typename ContainerType>
   struct delimiters<ContainerType, char>
   {
      using type = delimiter_values<char>;

      static constexpr type values = { "[", ", ", "]" };
   };

   /**
   * @brief Default wide delimiters for any container type that isn't specialized.
   */
   template<typename ContainerType>
   struct delimiters<ContainerType, wchar_t>
   {
      using type = delimiter_values<wchar_t>;

      static constexpr type values = { L"[", L", ", L"]" };
   };

   /**
   * @brief Narrow character specialization for std::set<...>.
   */
   template<
      typename Type,
      typename ComparatorType,
      typename AllocatorType
   >
   struct delimiters<std::set<Type, ComparatorType, AllocatorType>, char>
   {
      static constexpr delimiter_values<char> values = { "{", ", ", "}" };
   };

   /**
   * @brief Wide character specialization for std::set<...>.
   */
   template<
      typename Type,
      typename ComparatorType,
      typename AllocatorType
   >
   struct delimiters<std::set<Type, ComparatorType, AllocatorType>, wchar_t>
   {
      static constexpr delimiter_values<wchar_t> values = { L"{", L", ", L"}" };
   };

   /**
   * @brief Narrow character specialization for std::set<...>.
   */
   template<
      typename Type,
      typename ComparatorType,
      typename AllocatorType
   >
      struct delimiters<std::multiset<Type, ComparatorType, AllocatorType>, char>
   {
      static constexpr delimiter_values<char> values = { "{", ", ", "}" };
   };

   /**
   * @brief Wide character specialization for std::set<...>.
   */
   template<
      typename Type,
      typename ComparatorType,
      typename AllocatorType
   >
      struct delimiters<std::multiset<Type, ComparatorType, AllocatorType>, wchar_t>
   {
      static constexpr delimiter_values<wchar_t> values = { L"{", L", ", L"}" };
   };

   /**
   * @brief Narrow character specialization for std::pair<...>.
   */
   template<
      typename FirstType,
      typename SecondType
   >
   struct delimiters<std::pair<FirstType, SecondType>, char>
   {
      static constexpr delimiter_values<char> values = { "(", ", ", ")" };
   };

   /**
   * @brief Wide character specialization for std::pair<...>.
   */
   template<
      typename FirstType,
      typename SecondType
   >
   struct delimiters<std::pair<FirstType, SecondType>, wchar_t>
   {
      static constexpr delimiter_values<wchar_t> values = { L"(", L", ", L")" };
   };

   /**
   * @brief Narrow character specialization for std::tuple<...>.
   */
   template<typename... Types>
   struct delimiters<std::tuple<Types...>, char>
   {
      static constexpr delimiter_values<char> values = { "<", ", ", ">" };
   };

   /**
   * @brief Wide character specialization for std::tuple<...>.
   */
   template<typename... Types>
   struct delimiters<std::tuple<Types...>, wchar_t>
   {
      static constexpr delimiter_values<wchar_t> values = { L"<", L", ", L">" };
   };

   /**
   * @brief Recursive tuple helper template to print std::tuple<...> objects.
   */
   template<
      typename TupleType,
      std::size_t N
   >
   struct TuplePrinter
   {
      template<
         typename CharacterType,
         typename TraitsType,
         typename DelimiterValues
      >
      inline static void Print(
         std::basic_ostream<CharacterType, TraitsType>& stream,
         const TupleType& container,
         const DelimiterValues& delimiters)
      {
         TuplePrinter<TupleType, N - 1>::Print(stream, container, delimiters);

         stream
            << delimiters.separator
            << std::get<N - 1>(container);
      }
   };

   /**
   * @brief Specialization of tuple helper to handle empty std::tuple<...> objects.
   */
   template<typename TupleType>
   struct TuplePrinter<TupleType, 0>
   {
      template<
         typename CharacterType,
         typename TraitsType,
         typename DelimiterValues
      >
         inline static void Print(
            std::basic_ostream<CharacterType, TraitsType>& /*stream*/,
            const TupleType& /*tuple*/,
            const DelimiterValues& /*delimiters*/)
      {
      };
   };

   /**
   * @brief Specialization of tuple helper for the first index of a std::tuple<...>
   */
   template<typename TupleType>
   struct TuplePrinter<TupleType, 1>
   {
      template<
         typename CharacterType,
         typename TraitsType,
         typename DelimiterValues
      >
      inline static void Print(
         std::basic_ostream<CharacterType, TraitsType>& stream,
         const TupleType& tuple,
         const DelimiterValues& /*delimiters*/)
      {
         stream << std::get<0>(tuple);
      }
   };

   /**
   * @brief Specialization for non-zero indices of a std::tuple<...>.
   */
   template<
      typename CharacterType,
      typename TraitsType,
      typename... TupleArgs
   >
   inline static void PrintingHelper(
      std::basic_ostream<CharacterType, TraitsType>& stream,
      const std::tuple<TupleArgs...>& container)
   {
      static constexpr auto delimiters =
         Printer::delimiters<
            std::decay_t<decltype(container)>,
            CharacterType
         >::values;

      stream << delimiters.prefix;
      TuplePrinter<decltype(container), sizeof...(TupleArgs)>::Print(stream, container, delimiters);
      stream << delimiters.suffix;
   }

   /**
   * @brief Helper function to determine if a container is empty.
   */
   template<typename ContainerType>
   inline bool IsEmpty(const ContainerType& container)
   {
      return container.empty();
   };

   /**
   * @brief Helper function to be selected for non-empty arrays.
   */
   template<
      typename ArrayType,
      std::size_t ArraySize
   >
   constexpr bool IsEmpty(const ArrayType(&)[ArraySize])
   {
      return false;
   }

   /**
   * @brief Helper function to be selected for empty arrays.
   */
   template<
      typename ArrayType,
      std::size_t /*ArraySize*/
   >
   constexpr bool IsEmpty(const ArrayType(&)[0])
   {
      return true;
   }

   /**
   * @brief Printing specialization suitable for most container types.
   */
   template<
      typename ContainerType,
      typename CharacterType,
      typename TraitsType
   >
   inline static void PrintingHelper(
      std::basic_ostream<CharacterType, TraitsType>& stream,
      const ContainerType& container)
   {
      static constexpr auto delimiters = Printer::delimiters<ContainerType, CharacterType>::values;

      if (IsEmpty(container))
      {
         stream
            << delimiters.prefix
            << delimiters.suffix;

         return;
      }

      auto begin = std::begin(container);
      stream << delimiters.prefix << *begin;
      std::advance(begin, 1);

      std::for_each(begin, std::end(container),
         [&stream] (const auto& value)
      {
         stream << delimiters.separator << value;
      });

      stream << delimiters.suffix;
   }

   /**
   * @brief Printing specialization for std::pair<...>.
   */
   template<
      typename FirstType,
      typename SecondType,
      typename CharacterType,
      typename TraitsType
   >
   inline static void PrintingHelper(
      std::basic_ostream<CharacterType, TraitsType>& stream,
      const std::pair<FirstType, SecondType>& container)
   {
      static constexpr auto delimiters =
         Printer::delimiters<
            std::decay_t<decltype(container)>,
            CharacterType
         >::values;

      stream
         << delimiters.prefix
         << container.first
         << delimiters.separator
         << container.second
         << delimiters.suffix;
   }

   /**
   * @brief Main class that will print out the container with the help of various templated
   * helper functions.
   */
   template<
      typename ContainerType,
      typename CharacterType,
      typename TraitsType
   >
   class ContainerPrinter
   {
   public:
      ContainerPrinter(const ContainerType& container)
         : m_container{ container }
      {
      }

      inline void PrintTo(std::basic_ostream<CharacterType, TraitsType>& stream) const
      {
         PrintingHelper(stream, m_container);
      }

   private:
      const ContainerType& m_container;
   };
}

/**
* @brief Overload of the stream output operator for compatible containers.
*/
template<
   typename ContainerType,
   typename CharacterType,
   typename TraitsType,
   typename = std::enable_if_t<Traits::is_printable_as_container_v<ContainerType>>
>
auto& operator<<(
   std::basic_ostream<CharacterType, TraitsType>& stream,
   const ContainerType& container)
{
   Printer::ContainerPrinter<ContainerType, CharacterType, TraitsType>(container).PrintTo(stream);

   return stream;
}
<commit_msg>Clean Up<commit_after>#pragma once

#include <cstddef>
#include <iostream>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

namespace Traits
{
   /**
   * @brief A neat SFINAE trick.
   */
   template<class...>
   using void_t = void;

   /**
   * @brief Base case for the testing of STD compatible container types.
   */
   template<
      typename /*Type*/,
      typename = void
   >
   struct is_printable_as_container : std::false_type
   {
   };

   /**
   * @brief Specialization to ensure that Standard Library compatible containers that have
   * `begin()`, `end()`, and `empty()` member functions, as well as the `value_type` and
   * `iterator` typedefs, are treated as printable containers.
   */
   template<typename Type>
   struct is_printable_as_container<
      Type,
      void_t<
         decltype(std::declval<Type&>().begin()),
         decltype(std::declval<Type&>().end()),
         decltype(std::declval<Type&>().empty()),
         typename Type::value_type,
         typename Type::iterator
      >
   > : public std::true_type
   {
   };

   /**
   * @brief Specialization to treat std::pair<...> as a printable container type.
   */
   template<
      typename FirstType,
      typename SecondType
   >
   struct is_printable_as_container<std::pair<FirstType, SecondType>> : public std::true_type
   {
   };

   /**
   * @brief Specialization to treat std::tuple<...> as a printable container type.
   */
   template<typename... DataTypes>
   struct is_printable_as_container<std::tuple<DataTypes...>> : public std::true_type
   {
   };

   /**
   * @brief Specialization to treat arrays as printable container types.
   */
   template<
      typename ArrayType,
      std::size_t ArraySize
   >
   struct is_printable_as_container<ArrayType[ArraySize]> : public std::true_type
   {
   };

   /**
   * @brief Narrow character array specialization in order to ensure that we print character arrays
   * as string and not as delimiter containers.
   */
   template<std::size_t ArraySize>
   struct is_printable_as_container<char[ArraySize]> : public std::false_type
   {
   };

   /**
   * @brief Wide character array specialization in order to ensure that we print character arrays
   * as string and not as delimiter containers.
   */
   template<std::size_t ArraySize>
   struct is_printable_as_container<wchar_t[ArraySize]> : public std::false_type
   {
   };

   /**
   * @brief String specialization in order to ensure that we treat strings as nothing more than strings.
   */
   template<
      typename CharacterType,
      typename TraitsType,
      typename AllocatorType
   >
   struct is_printable_as_container<
      std::basic_string<
         CharacterType,
         TraitsType,
         AllocatorType
      >
   > : public std::false_type
   {
   };

   /**
   * @brief Helper variable template.
   */
   template<typename Type>
   constexpr bool is_printable_as_container_v = is_printable_as_container<Type>::value;
}

namespace Printer
{
   /**
   * @brief Struct to neatly wrap up all the additional characters we'll need in order to
   * print out the containers.
   */
   template<typename DelimiterType>
   struct delimiter_values
   {
      using type = DelimiterType;

      const type* prefix;
      const type* separator;
      const type* suffix;
   };

   /**
   * @brief Additional wrapper around the `delimiter_values` struct for added convenience.
   */
   template<
      typename /*ContainerType*/,
      typename DelimiterType
   >
   struct delimiters
   {
      using type = delimiter_values<DelimiterType>;

      static const type values;
   };

   /**
   * @brief Default narrow delimiters for any container type that isn't specialized.
   */
   template<typename ContainerType>
   struct delimiters<ContainerType, char>
   {
      using type = delimiter_values<char>;

      static constexpr type values = { "[", ", ", "]" };
   };

   /**
   * @brief Default wide delimiters for any container type that isn't specialized.
   */
   template<typename ContainerType>
   struct delimiters<ContainerType, wchar_t>
   {
      using type = delimiter_values<wchar_t>;

      static constexpr type values = { L"[", L", ", L"]" };
   };

   /**
   * @brief Narrow character specialization for std::set<...>.
   */
   template<
      typename Type,
      typename ComparatorType,
      typename AllocatorType
   >
   struct delimiters<std::set<Type, ComparatorType, AllocatorType>, char>
   {
      static constexpr delimiter_values<char> values = { "{", ", ", "}" };
   };

   /**
   * @brief Wide character specialization for std::set<...>.
   */
   template<
      typename Type,
      typename ComparatorType,
      typename AllocatorType
   >
   struct delimiters<std::set<Type, ComparatorType, AllocatorType>, wchar_t>
   {
      static constexpr delimiter_values<wchar_t> values = { L"{", L", ", L"}" };
   };

   /**
   * @brief Narrow character specialization for std::multiset<...>.
   */
   template<
      typename Type,
      typename ComparatorType,
      typename AllocatorType
   >
   struct delimiters<std::multiset<Type, ComparatorType, AllocatorType>, char>
   {
      static constexpr delimiter_values<char> values = { "{", ", ", "}" };
   };

   /**
   * @brief Wide character specialization for std::multiset<...>.
   */
   template<
      typename Type,
      typename ComparatorType,
      typename AllocatorType
   >
   struct delimiters<std::multiset<Type, ComparatorType, AllocatorType>, wchar_t>
   {
      static constexpr delimiter_values<wchar_t> values = { L"{", L", ", L"}" };
   };

   /**
   * @brief Narrow character specialization for std::pair<...>.
   */
   template<
      typename FirstType,
      typename SecondType
   >
   struct delimiters<std::pair<FirstType, SecondType>, char>
   {
      static constexpr delimiter_values<char> values = { "(", ", ", ")" };
   };

   /**
   * @brief Wide character specialization for std::pair<...>.
   */
   template<
      typename FirstType,
      typename SecondType
   >
   struct delimiters<std::pair<FirstType, SecondType>, wchar_t>
   {
      static constexpr delimiter_values<wchar_t> values = { L"(", L", ", L")" };
   };

   /**
   * @brief Narrow character specialization for std::tuple<...>.
   */
   template<typename... Types>
   struct delimiters<std::tuple<Types...>, char>
   {
      static constexpr delimiter_values<char> values = { "<", ", ", ">" };
   };

   /**
   * @brief Wide character specialization for std::tuple<...>.
   */
   template<typename... Types>
   struct delimiters<std::tuple<Types...>, wchar_t>
   {
      static constexpr delimiter_values<wchar_t> values = { L"<", L", ", L">" };
   };

   /**
   * @brief Recursive tuple helper template to print std::tuple<...> objects.
   */
   template<
      typename TupleType,
      std::size_t N
   >
   struct tuple_printer
   {
      template<
         typename CharacterType,
         typename TraitsType,
         typename DelimiterValues
      >
      inline static void print(
         std::basic_ostream<CharacterType, TraitsType>& stream,
         const TupleType& container,
         const DelimiterValues& delimiters)
      {
         tuple_printer<TupleType, N - 1>::print(stream, container, delimiters);

         stream
            << delimiters.separator
            << std::get<N - 1>(container);
      }
   };

   /**
   * @brief Specialization of tuple helper to handle empty std::tuple<...> objects.
   */
   template<typename TupleType>
   struct tuple_printer<TupleType, 0>
   {
      template<
         typename CharacterType,
         typename TraitsType,
         typename DelimiterValues
      >
      inline static void print(
         std::basic_ostream<CharacterType, TraitsType>& /*stream*/,
         const TupleType& /*tuple*/,
         const DelimiterValues& /*delimiters*/)
      {
      };
   };

   /**
   * @brief Specialization of tuple helper for the first index of a std::tuple<...>
   */
   template<typename TupleType>
   struct tuple_printer<TupleType, 1>
   {
      template<
         typename CharacterType,
         typename TraitsType,
         typename DelimiterValues
      >
      inline static void print(
         std::basic_ostream<CharacterType, TraitsType>& stream,
         const TupleType& tuple,
         const DelimiterValues& /*delimiters*/)
      {
         stream << std::get<0>(tuple);
      }
   };

   /**
   * @brief Specialization for non-zero indices of a std::tuple<...>.
   */
   template<
      typename CharacterType,
      typename TraitsType,
      typename... TupleArgs
   >
   inline static void printing_helper(
      std::basic_ostream<CharacterType, TraitsType>& stream,
      const std::tuple<TupleArgs...>& container)
   {
      static constexpr auto delimiters =
         Printer::delimiters<
            std::decay_t<decltype(container)>,
            CharacterType
         >::values;

      stream << delimiters.prefix;
      tuple_printer<decltype(container), sizeof...(TupleArgs)>::print(stream, container, delimiters);
      stream << delimiters.suffix;
   }

   /**
   * @brief Helper function to determine if a container is empty.
   */
   template<typename ContainerType>
   inline bool is_empty(const ContainerType& container)
   {
      return container.empty();
   };

   /**
   * @brief Helper function to be selected for non-empty arrays.
   */
   template<
      typename ArrayType,
      std::size_t ArraySize
   >
   constexpr bool is_empty(const ArrayType(&)[ArraySize])
   {
      return false;
   }

   /**
   * @brief Helper function to be selected for empty arrays.
   */
   template<
      typename ArrayType,
      std::size_t /*ArraySize*/
   >
   constexpr bool is_empty(const ArrayType(&)[0])
   {
      return true;
   }

   /**
   * @brief Printing specialization suitable for most container types.
   */
   template<
      typename ContainerType,
      typename CharacterType,
      typename TraitsType
   >
   inline static void printing_helper(
      std::basic_ostream<CharacterType, TraitsType>& stream,
      const ContainerType& container)
   {
      static constexpr auto delimiters = Printer::delimiters<ContainerType, CharacterType>::values;

      if (is_empty(container))
      {
         stream
            << delimiters.prefix
            << delimiters.suffix;

         return;
      }

      auto begin = std::begin(container);
      stream << delimiters.prefix << *begin;
      std::advance(begin, 1);

      std::for_each(begin, std::end(container),
         [&stream] (const auto& value)
      {
         stream << delimiters.separator << value;
      });

      stream << delimiters.suffix;
   }

   /**
   * @brief Printing specialization for std::pair<...>.
   */
   template<
      typename FirstType,
      typename SecondType,
      typename CharacterType,
      typename TraitsType
   >
   inline static void printing_helper(
      std::basic_ostream<CharacterType, TraitsType>& stream,
      const std::pair<FirstType, SecondType>& container)
   {
      static constexpr auto delimiters =
         Printer::delimiters<
            std::decay_t<decltype(container)>,
            CharacterType
         >::values;

      stream
         << delimiters.prefix
         << container.first
         << delimiters.separator
         << container.second
         << delimiters.suffix;
   }

   /**
   * @brief Main class that will print out the container with the help of various templated
   * helper functions.
   */
   template<
      typename ContainerType,
      typename CharacterType,
      typename TraitsType
   >
   class ContainerPrinter
   {
   public:
      ContainerPrinter(const ContainerType& container)
         : m_container{ container }
      {
      }

      inline void print_to(std::basic_ostream<CharacterType, TraitsType>& stream) const
      {
         printing_helper(stream, m_container);
      }

   private:
      const ContainerType& m_container;
   };
}

/**
* @brief Overload of the stream output operator for compatible containers.
*/
template<
   typename ContainerType,
   typename CharacterType,
   typename TraitsType,
   typename = std::enable_if_t<Traits::is_printable_as_container_v<ContainerType>>
>
auto& operator<<(
   std::basic_ostream<CharacterType, TraitsType>& stream,
   const ContainerType& container)
{
   Printer::ContainerPrinter<ContainerType, CharacterType, TraitsType>(container).print_to(stream);

   return stream;
}
<|endoftext|>


<commit_before>#include "ZambeziManager.h"
#include "ZambeziMiningTask.h"

#include "../group-manager/PropValueTable.h" // pvid_t
#include "../group-manager/GroupManager.h"
#include "../attr-manager/AttrManager.h"
#include "../attr-manager/AttrTable.h"

#include <common/PropSharedLock.h>
#include <configuration-manager/ZambeziConfig.h>
#include <util/ClockTimer.h>
#include <glog/logging.h>
#include <fstream>
#include <math.h>
#include <algorithm>

using namespace sf1r;

namespace
{
const izenelib::ir::Zambezi::Algorithm kAlgorithm =
    izenelib::ir::Zambezi::SVS;
}

ZambeziManager::ZambeziManager(
        const ZambeziConfig& config,
        faceted::AttrManager* attrManager,
        NumericPropertyTableBuilder* numericTableBuilder)
    : config_(config)
    , attrManager_(attrManager)
    , indexer_(config_.poolSize, config_.poolCount, config_.reverse)
    , numericTableBuilder_(numericTableBuilder)
{
}

bool ZambeziManager::open()
{
    const std::string& path = config_.indexFilePath;
    std::ifstream ifs(path.c_str(), std::ios_base::binary);

    if (! ifs)
        return true;

    LOG(INFO) << "loading zambezi index path: " << path;

    try
    {
        indexer_.load(ifs);
    }
    catch (const std::exception& e)
    {
        LOG(ERROR) << "exception in read file: " << e.what()
                   << ", path: " << path;
        return false;
    }

    LOG(INFO) << "finished loading zambezi index, total doc num: "
              << indexer_.totalDocNum();

    return true;
}

MiningTask* ZambeziManager::createMiningTask(DocumentManager& documentManager)
{
    return new ZambeziMiningTask(config_, documentManager, indexer_);
}

void ZambeziManager::search(
    const std::vector<std::pair<std::string, int> >& tokens,
    const boost::function<bool(uint32_t)>& filter,
    uint32_t limit,
    std::vector<docid_t>& docids,
    std::vector<uint32_t>& scores)
{
    izenelib::util::ClockTimer timer;

    indexer_.retrievalAndFiltering(kAlgorithm, tokens, filter, limit, false, docids, scores);

    LOG(INFO) << "zambezi returns docid num: " << docids.size()
              << ", costs :" << timer.elapsed() << " seconds";
}

void ZambeziManager::NormalizeScore(
    std::vector<docid_t>& docids,
    std::vector<float>& scores,
    std::vector<float>& productScores,
    PropSharedLockSet &sharedLockSet)
{
    faceted::AttrTable* attTable = NULL;

    if (attrManager_)
    {
        attTable = &(attrManager_->getAttrTable());
        sharedLockSet.insertSharedLock(attTable);
    }
    float maxScore = 1;

    std::string propName = "itemcount";
    std::string propName_comment = "CommentCount";

    boost::shared_ptr<NumericPropertyTableBase> numericTable =
        numericTableBuilder_->createPropertyTable(propName);

    boost::shared_ptr<NumericPropertyTableBase> numericTable_comment =
        numericTableBuilder_->createPropertyTable(propName_comment);

    if (numericTable)
        sharedLockSet.insertSharedLock(numericTable.get());

    if (numericTable_comment)
        sharedLockSet.insertSharedLock(numericTable_comment.get());

    for (uint32_t i = 0; i < docids.size(); ++i)
    {
        uint32_t attr_size = 1;
        if (attTable)
        {
            faceted::AttrTable::ValueIdList attrvids;
            attTable->getValueIdList(docids[i], attrvids);
            attr_size = std::min(attrvids.size(), size_t(10));
        }

        int32_t itemcount = 1;
        if (numericTable)
        {
            numericTable->getInt32Value(docids[i], itemcount, false);
            attr_size += std::min(itemcount, 50);
        }

        if (numericTable_comment)
        {
            int32_t commentcount = 1;
            numericTable_comment->getInt32Value(docids[i], commentcount, false);
            if (itemcount != 0)
                attr_size += std::min(commentcount/itemcount, 100);
            else
                attr_size += std::min(commentcount, 100);

        }

        scores[i] = scores[i] * pow(attr_size, 0.3);
        if (scores[i] > maxScore)
            maxScore = scores[i];
    }

    for (unsigned int i = 0; i < scores.size(); ++i)
    {
        scores[i] = int(scores[i] / maxScore * 100) + productScores[i];
    }
}
<commit_msg>weight up commentnumber<commit_after>#include "ZambeziManager.h"
#include "ZambeziMiningTask.h"

#include "../group-manager/PropValueTable.h" // pvid_t
#include "../group-manager/GroupManager.h"
#include "../attr-manager/AttrManager.h"
#include "../attr-manager/AttrTable.h"

#include <common/PropSharedLock.h>
#include <configuration-manager/ZambeziConfig.h>
#include <util/ClockTimer.h>
#include <glog/logging.h>
#include <fstream>
#include <math.h>
#include <algorithm>

using namespace sf1r;

namespace
{
const izenelib::ir::Zambezi::Algorithm kAlgorithm =
    izenelib::ir::Zambezi::SVS;
}

ZambeziManager::ZambeziManager(
        const ZambeziConfig& config,
        faceted::AttrManager* attrManager,
        NumericPropertyTableBuilder* numericTableBuilder)
    : config_(config)
    , attrManager_(attrManager)
    , indexer_(config_.poolSize, config_.poolCount, config_.reverse)
    , numericTableBuilder_(numericTableBuilder)
{
}

bool ZambeziManager::open()
{
    const std::string& path = config_.indexFilePath;
    std::ifstream ifs(path.c_str(), std::ios_base::binary);

    if (! ifs)
        return true;

    LOG(INFO) << "loading zambezi index path: " << path;

    try
    {
        indexer_.load(ifs);
    }
    catch (const std::exception& e)
    {
        LOG(ERROR) << "exception in read file: " << e.what()
                   << ", path: " << path;
        return false;
    }

    LOG(INFO) << "finished loading zambezi index, total doc num: "
              << indexer_.totalDocNum();

    return true;
}

MiningTask* ZambeziManager::createMiningTask(DocumentManager& documentManager)
{
    return new ZambeziMiningTask(config_, documentManager, indexer_);
}

void ZambeziManager::search(
    const std::vector<std::pair<std::string, int> >& tokens,
    const boost::function<bool(uint32_t)>& filter,
    uint32_t limit,
    std::vector<docid_t>& docids,
    std::vector<uint32_t>& scores)
{
    izenelib::util::ClockTimer timer;

    indexer_.retrievalAndFiltering(kAlgorithm, tokens, filter, limit, false, docids, scores);

    LOG(INFO) << "zambezi returns docid num: " << docids.size()
              << ", costs :" << timer.elapsed() << " seconds";
}

void ZambeziManager::NormalizeScore(
    std::vector<docid_t>& docids,
    std::vector<float>& scores,
    std::vector<float>& productScores,
    PropSharedLockSet &sharedLockSet)
{
    faceted::AttrTable* attTable = NULL;

    if (attrManager_)
    {
        attTable = &(attrManager_->getAttrTable());
        sharedLockSet.insertSharedLock(attTable);
    }
    float maxScore = 1;

    std::string propName = "itemcount";
    std::string propName_comment = "CommentCount";

    boost::shared_ptr<NumericPropertyTableBase> numericTable =
        numericTableBuilder_->createPropertyTable(propName);

    boost::shared_ptr<NumericPropertyTableBase> numericTable_comment =
        numericTableBuilder_->createPropertyTable(propName_comment);

    if (numericTable)
        sharedLockSet.insertSharedLock(numericTable.get());

    if (numericTable_comment)
        sharedLockSet.insertSharedLock(numericTable_comment.get());

    for (uint32_t i = 0; i < docids.size(); ++i)
    {
        uint32_t attr_size = 1;
        if (attTable)
        {
            faceted::AttrTable::ValueIdList attrvids;
            attTable->getValueIdList(docids[i], attrvids);
            attr_size = std::min(attrvids.size(), size_t(10));
        }

        int32_t itemcount = 1;
        if (numericTable)
        {
            numericTable->getInt32Value(docids[i], itemcount, false);
            attr_size += std::min(itemcount, 50);
        }

        if (numericTable_comment)
        {
            int32_t commentcount = 1;
            numericTable_comment->getInt32Value(docids[i], commentcount, false);
            attr_size += pow(std::min((float)commentcount/sqrt(itemcount+1), 500.),1.3);
        }

        scores[i] = scores[i] * pow(attr_size, 0.5);
        if (scores[i] > maxScore)
            maxScore = scores[i];
    }

    for (unsigned int i = 0; i < scores.size(); ++i)
    {
        scores[i] = int(scores[i] / maxScore * 100) + productScores[i];
    }
}
<|endoftext|>


<commit_before>// Reversible classical circuits
// Source: ./examples/reversible.cpp
#include <iostream>

#include "qpp.h"

int main() {
    using namespace qpp;
    std::cout << ">> Classical reversible circuits. ";
    std::cout << "Bits are labeled from right to left,\n   ";
    std::cout << "i.e. bit zero is the least significant bit (rightmost).\n";

    Dynamic_bitset bits{4};                                // 4 classical bits
    std::cout << ">> Initial bitset:\n\t" << bits << '\n'; // display them

    bits.rand(); // randomize the bits
    std::cout << ">> After randomization:\n\t" << bits << '\n'; // display them

    Bit_circuit bit_circuit{bits}; // bit circuit

    std::cout << ">> Apply X_0, followed by CNOT_02, CNOT_13 and TOF_013\n";
    bit_circuit.X(0); // apply a NOT gate on first bit
    bit_circuit.CNOT({0, 2}).CNOT({1, 3}).TOF({0, 1, 3}); // sequence operations

    std::cout << ">> Final bit circuit:\n\t" << bit_circuit << '\n';
    std::cout << ">> 3rd bit: " << bit_circuit.get(2) << '\n';
    std::cout << ">> CNOT count: " << bit_circuit.gate_count.CNOT << '\n';

    bit_circuit.reset(); // resets the circuit
    std::cout << ">> Reseted circuit:\n\t" << bit_circuit << '\n';
    std::cout << ">> CNOT count: " << bit_circuit.gate_count.CNOT << '\n';
}
<commit_msg>commit<commit_after>// Reversible classical circuits
// Source: ./examples/reversible.cpp
#include <iostream>

#include "qpp.h"

int main() {
    using namespace qpp;
    std::cout << ">> Classical reversible circuits. ";
    std::cout << "Bits are labeled from right to left,\n   ";
    std::cout << "i.e. bit zero is the least significant bit (rightmost).\n";

    Dynamic_bitset bits{4};                                // 4 classical bits
    std::cout << ">> Initial bitset:\n\t" << bits << '\n'; // display them

    bits.rand(); // randomize the bits
    std::cout << ">> After randomization:\n\t" << bits << '\n'; // display them

    Bit_circuit bit_circuit{bits}; // bit circuit

    std::cout << ">> Apply X_0, followed by CNOT_02, CNOT_13 and TOF_013\n";
    bit_circuit.X(0); // apply a NOT gate on first bit
    bit_circuit.CNOT({0, 2}).CNOT({1, 3}).TOF({0, 1, 3}); // sequence operations

    std::cout << ">> Final bit circuit:\n\t" << bit_circuit << '\n';
    std::cout << ">> 3rd bit: " << bit_circuit.get(2) << '\n';
    std::cout << ">> CNOT count: " << bit_circuit.gate_count.CNOT << '\n';

    bit_circuit.reset(); // resets the circuit
    std::cout << ">> Reset circuit:\n\t" << bit_circuit << '\n';
    std::cout << ">> CNOT count: " << bit_circuit.gate_count.CNOT << '\n';
}
<|endoftext|>


<commit_before>#include <babylon/meshes/simplification/quadratic_matrix.h>

namespace BABYLON {

QuadraticMatrix::QuadraticMatrix()
{
  for (unsigned int i = 0; i < 10; ++i) {
    data[i] = 0.f;
  }
}

QuadraticMatrix::QuadraticMatrix(const std::array<float, 10>& _data)
{
  for (unsigned int i = 0; i < 10; ++i) {
    data[i] = _data[i];
  }
}

QuadraticMatrix::QuadraticMatrix(const QuadraticMatrix& other) = default;
QuadraticMatrix::QuadraticMatrix(QuadraticMatrix&& other) = default;
QuadraticMatrix& QuadraticMatrix::operator=(const QuadraticMatrix& other) = default;
QuadraticMatrix& QuadraticMatrix::operator=(QuadraticMatrix&& other) = default;

QuadraticMatrix::~QuadraticMatrix() = default;

float QuadraticMatrix::det(unsigned int a11, unsigned int a12, int unsigned a13,
                           unsigned int a21, unsigned int a22, unsigned int a23,
                           unsigned int a31, unsigned int a32, unsigned int a33)
{
  return data[a11] * data[a22] * data[a33] + data[a13] * data[a21] * data[a32]
         + data[a12] * data[a23] * data[a31] - data[a13] * data[a22] * data[a31]
         - data[a11] * data[a23] * data[a32]
         - data[a12] * data[a21] * data[a33];
}

void QuadraticMatrix::addInPlace(const QuadraticMatrix& matrix)
{
  for (unsigned int i = 0; i < 10; ++i) {
    data[i] += matrix.data[i];
  }
}

void QuadraticMatrix::addArrayInPlace(const std::array<float, 10>& _data)
{
  for (unsigned int i = 0; i < 10; ++i) {
    data[i] += _data[i];
  }
}

QuadraticMatrix QuadraticMatrix::add(const QuadraticMatrix& matrix)
{
  QuadraticMatrix m;
  for (unsigned int i = 0; i < 10; ++i) {
    m.data[i] = data[i] + matrix.data[i];
  }
  return m;
}

QuadraticMatrix QuadraticMatrix::FromData(float a, float b, float c, float d)
{
  return QuadraticMatrix(QuadraticMatrix::DataFromNumbers(a, b, c, d));
}

std::array<float, 10> QuadraticMatrix::DataFromNumbers(float a, float b,
                                                       float c, float d)
{
  return {{a * a, a * b, a * c, a * d, //
           b * b, b * c, b * d,        //
           c * c, c * d,               //
           d * d}};
}

} // end of namespace BABYLON
<commit_msg>Formatting<commit_after>#include <babylon/meshes/simplification/quadratic_matrix.h>

namespace BABYLON {

QuadraticMatrix::QuadraticMatrix()
{
  for (unsigned int i = 0; i < 10; ++i) {
    data[i] = 0.f;
  }
}

QuadraticMatrix::QuadraticMatrix(const std::array<float, 10>& _data)
{
  for (unsigned int i = 0; i < 10; ++i) {
    data[i] = _data[i];
  }
}

QuadraticMatrix::QuadraticMatrix(const QuadraticMatrix& other) = default;
QuadraticMatrix::QuadraticMatrix(QuadraticMatrix&& other)      = default;
QuadraticMatrix& QuadraticMatrix::operator=(const QuadraticMatrix& other) = default;
QuadraticMatrix& QuadraticMatrix::operator=(QuadraticMatrix&& other) = default;

QuadraticMatrix::~QuadraticMatrix() = default;

float QuadraticMatrix::det(unsigned int a11, unsigned int a12, int unsigned a13, unsigned int a21,
                           unsigned int a22, unsigned int a23, unsigned int a31, unsigned int a32,
                           unsigned int a33)
{
  return data[a11] * data[a22] * data[a33]   //
         + data[a13] * data[a21] * data[a32] //
         + data[a12] * data[a23] * data[a31] //
         - data[a13] * data[a22] * data[a31] //
         - data[a11] * data[a23] * data[a32] //
         - data[a12] * data[a21] * data[a33];
}

void QuadraticMatrix::addInPlace(const QuadraticMatrix& matrix)
{
  for (unsigned int i = 0; i < 10; ++i) {
    data[i] += matrix.data[i];
  }
}

void QuadraticMatrix::addArrayInPlace(const std::array<float, 10>& _data)
{
  for (unsigned int i = 0; i < 10; ++i) {
    data[i] += _data[i];
  }
}

QuadraticMatrix QuadraticMatrix::add(const QuadraticMatrix& matrix)
{
  QuadraticMatrix m;
  for (unsigned int i = 0; i < 10; ++i) {
    m.data[i] = data[i] + matrix.data[i];
  }
  return m;
}

QuadraticMatrix QuadraticMatrix::FromData(float a, float b, float c, float d)
{
  return QuadraticMatrix(QuadraticMatrix::DataFromNumbers(a, b, c, d));
}

std::array<float, 10> QuadraticMatrix::DataFromNumbers(float a, float b, float c, float d)
{
  return {{a * a, a * b, a * c, a * d, //
           b * b, b * c, b * d,        //
           c * c, c * d,               //
           d * d}};
}

} // end of namespace BABYLON
<|endoftext|>


<commit_before>#include <boost/algorithm/string/replace.hpp>
#include <cppcms/view.h>
#include <sstream>

#include "authentication_application.hpp"
#include "conversion_application.hpp"
#include "database_application.hpp"
#include "exceptions.hpp"
#include "jwt.hpp"
#include "kdb.h"
#include "root_application.hpp"
#include "service.hpp"
#include "user_application.hpp"

namespace kdbrest
{

/**
     * @brief Constructor for main service class
     *
     * @param srv Takes a CppCms service
     */
RootApp::RootApp (cppcms::service & srv) : cppcms::application (srv)
{

	attach (new AuthenticationApp (srv), "auth", "/auth{1}", // mapping
		"/auth(/(.*))?", 1				 // dispatching
		);

	attach (new UserApp (srv), "users", "/users{1}", // mapping
		"/users(/(.*))?", 1			 // dispatching
		);

	attach (new DatabaseApp (srv), "database", "/database{1}", // mapping
		"/database(/(.*))?", 1				   // dispatching
		);

	attach (new ConversionApp (srv), "conversion", "/conversion{1}", // mapping
		"/conversion(/(.*))?", 1				 // dispatching
		);

	dispatcher ().assign ("", &RootApp::welcome, this);
	mapper ().assign ("");

	dispatcher ().assign ("/version", &RootApp::version, this);
	mapper ().assign ("version", "/version");

	mapper ().root ("");
}

void RootApp::welcome ()
{
	if (request ().request_method () == "GET")
	{
		cppcms::base_content c;
		render ("rest_interface", c);
	}
	else
	{
		RootApp::setMethodNotAllowed (response ()); // send HTTP 405
		return;
	}
}

void RootApp::version ()
{
	if (request ().request_method () == "GET")
	{
		cppcms::json::value data;

		data["elektra"]["version"] = KDB_VERSION;
		data["elektra"]["major"] = KDB_VERSION_MAJOR;
		data["elektra"]["minor"] = KDB_VERSION_MINOR;
		data["elektra"]["micro"] = KDB_VERSION_MICRO;
		data["api"] = std::to_string (ELEKTRA_REST_API_VERSION);

		RootApp::setOk (response (), data, "application/json");
	}
	else
	{
		RootApp::setMethodNotAllowed (response ()); // send HTTP 405
		return;
	}
}

/* STATIC */

void RootApp::setOkRaw (cppcms::http::response & response, std::string & data, const std::string content_type)
{
	// send actual response
	if (!content_type.empty ())
	{
		response.set_content_header (content_type);
	}
	response.status (cppcms::http::response::ok);
	response.out () << data;
}

void RootApp::setOk (cppcms::http::response & response, cppcms::json::value & data, const std::string content_type)
{
	// send actual response
	if (!content_type.empty ())
	{
		response.set_content_header (content_type);
	}
	response.status (cppcms::http::response::ok);
	response.out () << data;
}

void RootApp::setOk (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::ok, message, loca);
}

void RootApp::setMethodNotAllowed (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::method_not_allowed, message, loca);
}

void RootApp::setNotAcceptable (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::not_acceptable, message, loca);
}

void RootApp::setUnprocessableEntity (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, 422, message, loca);
}

void RootApp::setUnauthorized (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::unauthorized, message, loca);
}

void RootApp::setBadRequest (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::bad_request, message, loca);
}

void RootApp::setNotFound (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::not_found, message, loca);
}

void RootApp::setInternalServerError (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::internal_server_error, message, loca);
}

cppcms::json::value RootApp::parsePostDataAsJson (cppcms::http::request & request)
{
	std::pair<void *, size_t> post_data = request.raw_post_data ();
	std::istringstream ss (std::string (reinterpret_cast<char const *> (post_data.first), post_data.second));
	cppcms::json::value data;
	if (!data.load (ss, true))
	{
		throw kdbrest::exception::InvalidPostDataFormatException ();
	}
	return data;
}

/* STATIC PRIVATE */

void RootApp::setHttpStatus (cppcms::http::response & response, const int status, const std::string & message, const std::string & loca)
{
	// send actual response
	response.content_type ("application/json");
	response.status (status);
	cppcms::json::value data;
	data["status"] = cppcms::http::response::status_to_string (status);
	if (!message.empty ())
	{
		data["message"] = message;
	}
	if (!loca.empty ())
	{
		data["i18n"] = loca;
	}
	response.out () << data;
}

void RootApp::setCORSHeaders (cppcms::http::response & response, const std::string allowedMethods)
{
	response.set_header ("Allow", allowedMethods);
	response.set_header ("Access-Control-Allow-Methods", allowedMethods);
	response.set_header ("Access-Control-Allow-Origin", ELEKTRA_REST_HEADER_RESPONSE_CORS_ORIGIN);
	response.set_header ("Access-Control-Allow-Headers", ELEKTRA_REST_HEADER_RESPONSE_CORS_HEADERS);
}

} // namespace kdbrest
<commit_msg>rest-backend: rename user endpoint<commit_after>#include <boost/algorithm/string/replace.hpp>
#include <cppcms/view.h>
#include <sstream>

#include "authentication_application.hpp"
#include "conversion_application.hpp"
#include "database_application.hpp"
#include "exceptions.hpp"
#include "jwt.hpp"
#include "kdb.h"
#include "root_application.hpp"
#include "service.hpp"
#include "user_application.hpp"

namespace kdbrest
{

/**
     * @brief Constructor for main service class
     *
     * @param srv Takes a CppCms service
     */
RootApp::RootApp (cppcms::service & srv) : cppcms::application (srv)
{

	attach (new AuthenticationApp (srv), "auth", "/auth{1}", // mapping
		"/auth(/(.*))?", 1				 // dispatching
		);

	attach (new UserApp (srv), "user", "/user{1}", // mapping
		"/user(/(.*))?", 1			 // dispatching
		);

	attach (new DatabaseApp (srv), "database", "/database{1}", // mapping
		"/database(/(.*))?", 1				   // dispatching
		);

	attach (new ConversionApp (srv), "conversion", "/conversion{1}", // mapping
		"/conversion(/(.*))?", 1				 // dispatching
		);

	dispatcher ().assign ("", &RootApp::welcome, this);
	mapper ().assign ("");

	dispatcher ().assign ("/version", &RootApp::version, this);
	mapper ().assign ("version", "/version");

	mapper ().root ("");
}

void RootApp::welcome ()
{
	if (request ().request_method () == "GET")
	{
		cppcms::base_content c;
		render ("rest_interface", c);
	}
	else
	{
		RootApp::setMethodNotAllowed (response ()); // send HTTP 405
		return;
	}
}

void RootApp::version ()
{
	if (request ().request_method () == "GET")
	{
		cppcms::json::value data;

		data["elektra"]["version"] = KDB_VERSION;
		data["elektra"]["major"] = KDB_VERSION_MAJOR;
		data["elektra"]["minor"] = KDB_VERSION_MINOR;
		data["elektra"]["micro"] = KDB_VERSION_MICRO;
		data["api"] = std::to_string (ELEKTRA_REST_API_VERSION);

		RootApp::setOk (response (), data, "application/json");
	}
	else
	{
		RootApp::setMethodNotAllowed (response ()); // send HTTP 405
		return;
	}
}

/* STATIC */

void RootApp::setOkRaw (cppcms::http::response & response, std::string & data, const std::string content_type)
{
	// send actual response
	if (!content_type.empty ())
	{
		response.set_content_header (content_type);
	}
	response.status (cppcms::http::response::ok);
	response.out () << data;
}

void RootApp::setOk (cppcms::http::response & response, cppcms::json::value & data, const std::string content_type)
{
	// send actual response
	if (!content_type.empty ())
	{
		response.set_content_header (content_type);
	}
	response.status (cppcms::http::response::ok);
	response.out () << data;
}

void RootApp::setOk (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::ok, message, loca);
}

void RootApp::setMethodNotAllowed (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::method_not_allowed, message, loca);
}

void RootApp::setNotAcceptable (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::not_acceptable, message, loca);
}

void RootApp::setUnprocessableEntity (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, 422, message, loca);
}

void RootApp::setUnauthorized (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::unauthorized, message, loca);
}

void RootApp::setBadRequest (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::bad_request, message, loca);
}

void RootApp::setNotFound (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::not_found, message, loca);
}

void RootApp::setInternalServerError (cppcms::http::response & response, const std::string message, const std::string loca)
{
	RootApp::setHttpStatus (response, cppcms::http::response::internal_server_error, message, loca);
}

cppcms::json::value RootApp::parsePostDataAsJson (cppcms::http::request & request)
{
	std::pair<void *, size_t> post_data = request.raw_post_data ();
	std::istringstream ss (std::string (reinterpret_cast<char const *> (post_data.first), post_data.second));
	cppcms::json::value data;
	if (!data.load (ss, true))
	{
		throw kdbrest::exception::InvalidPostDataFormatException ();
	}
	return data;
}

/* STATIC PRIVATE */

void RootApp::setHttpStatus (cppcms::http::response & response, const int status, const std::string & message, const std::string & loca)
{
	// send actual response
	response.content_type ("application/json");
	response.status (status);
	cppcms::json::value data;
	data["status"] = cppcms::http::response::status_to_string (status);
	if (!message.empty ())
	{
		data["message"] = message;
	}
	if (!loca.empty ())
	{
		data["i18n"] = loca;
	}
	response.out () << data;
}

void RootApp::setCORSHeaders (cppcms::http::response & response, const std::string allowedMethods)
{
	response.set_header ("Allow", allowedMethods);
	response.set_header ("Access-Control-Allow-Methods", allowedMethods);
	response.set_header ("Access-Control-Allow-Origin", ELEKTRA_REST_HEADER_RESPONSE_CORS_ORIGIN);
	response.set_header ("Access-Control-Allow-Headers", ELEKTRA_REST_HEADER_RESPONSE_CORS_HEADERS);
}

} // namespace kdbrest
<|endoftext|>


<commit_before>/*
 * Copyright 2008 The Native Client Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can
 * be found in the LICENSE file.
 */

#include "native_client/src/shared/platform/nacl_host_desc.h"
#include "native_client/src/shared/platform/nacl_log.h"
#include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
#include "native_client/src/trusted/desc/nacl_desc_base.h"
#include "native_client/src/trusted/desc/nacl_desc_io.h"
#include "native_client/src/trusted/desc/nrd_all_modules.h"

#include "gtest/gtest.h"

class SelLdrTest : public testing::Test {
 protected:
  virtual void SetUp();
  virtual void TearDown();
};

void SelLdrTest::SetUp() {
  NaClNrdAllModulesInit();
}

void SelLdrTest::TearDown() {
  NaClNrdAllModulesFini();
}

// set, get, setavail operations on the descriptor table
TEST_F(SelLdrTest, DescTable) {
  struct NaClApp app;
  struct NaClHostDesc *host_desc;
  struct NaClDesc* io_desc;
  struct NaClDesc* ret_desc;
  int ret_code;

  ret_code = NaClAppCtor(&app);
  ASSERT_EQ(1, ret_code);

  host_desc = (struct NaClHostDesc *) malloc(sizeof *host_desc);
  if (NULL == host_desc) {
    fprintf(stderr, "No memory\n");
  }
  ASSERT_TRUE(NULL != host_desc);

  io_desc = (struct NaClDesc *) NaClDescIoDescMake(host_desc);

  // 1st pos available is 0
  ret_code = NaClSetAvail(&app, io_desc);
  ASSERT_EQ(0, ret_code);
  // valid desc at pos 0
  ret_desc = NaClGetDesc(&app, 0);
  ASSERT_TRUE(NULL != ret_desc);

  // next pos available is 1
  ret_code = NaClSetAvail(&app, NULL);
  ASSERT_EQ(1, ret_code);
  // no desc at pos 1
  ret_desc = NaClGetDesc(&app, 1);
  ASSERT_TRUE(NULL == ret_desc);

  // no desc at pos 1 -> pos 1 is available
  ret_code = NaClSetAvail(&app, io_desc);
  ASSERT_EQ(1, ret_code);

  // valid desc at pos 1
  ret_desc = NaClGetDesc(&app, 1);
  ASSERT_TRUE(NULL != ret_desc);

  // set no desc at pos 3
  NaClSetDesc(&app, 3, NULL);

  // valid desc at pos 4
  NaClSetDesc(&app, 4, io_desc);
  ret_desc = NaClGetDesc(&app, 4);
  ASSERT_TRUE(NULL != ret_desc);

  // never set a desc at pos 10
  ret_desc = NaClGetDesc(&app, 10);
  ASSERT_TRUE(NULL == ret_desc);
}

// create service socket
TEST_F(SelLdrTest, CreateServiceSocket) {
  struct NaClApp app;
  int ret_code;

  ret_code = NaClAppCtor(&app);
  ASSERT_EQ(1, ret_code);

  // CreateServiceSocket sets the app service_port to a service port
  // desc and service_address to a service
  ASSERT_TRUE(NULL == app.service_port);
  ASSERT_TRUE(NULL == app.service_address);
  NaClCreateServiceSocket(&app);
  ASSERT_TRUE(NULL != app.service_port);
  ASSERT_TRUE(NULL != app.service_address);
}

// add and remove operations on the threads table
// Remove thread from an empty table is tested in a death test.
// TODO(tuduce): specify the death test name when checking in.
TEST_F(SelLdrTest, ThreadTableTest) {
  struct NaClApp app;
  struct NaClAppThread nat, *appt=&nat;
  int ret_code;

  ret_code = NaClAppCtor(&app);
  ASSERT_EQ(1, ret_code);

  // 1st pos available is 0
  ASSERT_EQ(0, app.num_threads);
  ret_code = NaClAddThread(&app, appt);
  ASSERT_EQ(0, ret_code);
  ASSERT_EQ(1, app.num_threads);

  // next pos available is 1
  ret_code = NaClAddThread(&app, NULL);
  ASSERT_EQ(1, ret_code);
  ASSERT_EQ(2, app.num_threads);

  // no thread at pos 1 -> pos 1 is available
  ret_code = NaClAddThread(&app, appt);
  ASSERT_EQ(1, ret_code);
  ASSERT_EQ(3, app.num_threads);

  NaClRemoveThread(&app, 0);
  ASSERT_EQ(2, app.num_threads);
}
<commit_msg>this change makes the test leak memory rather than have a non-deterministic race. Review URL: http://codereview.chromium.org/7082022<commit_after>/*
 * Copyright (c) 2011 The Native Client Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "native_client/src/shared/platform/nacl_host_desc.h"
#include "native_client/src/shared/platform/nacl_log.h"
#include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
#include "native_client/src/trusted/service_runtime/sel_ldr.h"
#include "native_client/src/trusted/desc/nacl_desc_base.h"
#include "native_client/src/trusted/desc/nacl_desc_io.h"
#include "native_client/src/trusted/desc/nrd_all_modules.h"

#include "gtest/gtest.h"

//
// There are several bugs in how these tests are set up.
//
// 1. NaCl modules such as the Log module are supposed to be
// initialized at process startup and finalized at shutdown.  In
// particular, there should not be any threads other than the main
// thread running when the Log module initializes, since the verbosity
// level is set then -- and thereafter it is assumed to be invariant
// and read without acquring locks.
//
// 2. NaClApp objects, while they don't have a Dtor, are expected to
// have a lifetime equal to that of the process that contain them.  In
// particular, when the untrusted thread invokes the exit syscall, it
// expects to be able to use _exit to exit, killing all other
// untrusted threads as a side effect.  Furthermore, once a NaClApp
// object is initialized, system service threads may be running holdin
// references to the NaClApp object.  If the NaClApp object goes out
// of scope or is otherwise destroyed and its memory freed, then these
// system thread will probably access memory that is no longer valid.
//
// These tests used to create NaClApp objects on the stack.  This
// means that random system service threads have pointers into the
// stack.  When a test function exits, the service threads now have a
// pointer into memory that will be overwritten by the next test
// function -- possibly to hold a different NaClApp object.  This
// makes the test fail in a non-deterministic manner: if the system
// service threads becomes quiescent before the main test thread
// returns, then things will be fine.
//
// These tests now dynamically allocate the NaClApp objects.  This
// means we leak memory.

class SelLdrTest : public testing::Test {
 protected:
  virtual void SetUp();
  virtual void TearDown();
};

void SelLdrTest::SetUp() {
  NaClNrdAllModulesInit();
}

void SelLdrTest::TearDown() {
  NaClNrdAllModulesFini();
}

// set, get, setavail operations on the descriptor table
TEST_F(SelLdrTest, DescTable) {
  struct NaClApp *app = (struct NaClApp *) malloc(sizeof *app);
  struct NaClHostDesc *host_desc;
  struct NaClDesc* io_desc;
  struct NaClDesc* ret_desc;
  int ret_code;

  ASSERT_TRUE(NULL != app);

  ret_code = NaClAppCtor(app);
  ASSERT_EQ(1, ret_code);

  host_desc = (struct NaClHostDesc *) malloc(sizeof *host_desc);
  if (NULL == host_desc) {
    fprintf(stderr, "No memory\n");
  }
  ASSERT_TRUE(NULL != host_desc);

  io_desc = (struct NaClDesc *) NaClDescIoDescMake(host_desc);

  // 1st pos available is 0
  ret_code = NaClSetAvail(app, io_desc);
  ASSERT_EQ(0, ret_code);
  // valid desc at pos 0
  ret_desc = NaClGetDesc(app, 0);
  ASSERT_TRUE(NULL != ret_desc);

  // next pos available is 1
  ret_code = NaClSetAvail(app, NULL);
  ASSERT_EQ(1, ret_code);
  // no desc at pos 1
  ret_desc = NaClGetDesc(app, 1);
  ASSERT_TRUE(NULL == ret_desc);

  // no desc at pos 1 -> pos 1 is available
  ret_code = NaClSetAvail(app, io_desc);
  ASSERT_EQ(1, ret_code);

  // valid desc at pos 1
  ret_desc = NaClGetDesc(app, 1);
  ASSERT_TRUE(NULL != ret_desc);

  // set no desc at pos 3
  NaClSetDesc(app, 3, NULL);

  // valid desc at pos 4
  NaClSetDesc(app, 4, io_desc);
  ret_desc = NaClGetDesc(app, 4);
  ASSERT_TRUE(NULL != ret_desc);

  // never set a desc at pos 10
  ret_desc = NaClGetDesc(app, 10);
  ASSERT_TRUE(NULL == ret_desc);
}

// create service socket
TEST_F(SelLdrTest, CreateServiceSocket) {
  struct NaClApp *app = (struct NaClApp *) malloc(sizeof *app);
  int ret_code;

  ASSERT_TRUE(NULL != app);

  ret_code = NaClAppCtor(app);
  ASSERT_EQ(1, ret_code);

  // CreateServiceSocket sets the app service_port to a service port
  // desc and service_address to a service
  ASSERT_TRUE(NULL == app->service_port);
  ASSERT_TRUE(NULL == app->service_address);
  NaClCreateServiceSocket(app);
  ASSERT_TRUE(NULL != app->service_port);
  ASSERT_TRUE(NULL != app->service_address);
}

// add and remove operations on the threads table
// Remove thread from an empty table is tested in a death test.
// TODO(tuduce): specify the death test name when checking in.
TEST_F(SelLdrTest, ThreadTableTest) {
  struct NaClApp *app = (struct NaClApp *) malloc(sizeof *app);
  struct NaClAppThread nat, *appt=&nat;
  int ret_code;

  ASSERT_TRUE(NULL != app);

  ret_code = NaClAppCtor(app);
  ASSERT_EQ(1, ret_code);

  // 1st pos available is 0
  ASSERT_EQ(0, app->num_threads);
  ret_code = NaClAddThread(app, appt);
  ASSERT_EQ(0, ret_code);
  ASSERT_EQ(1, app->num_threads);

  // next pos available is 1
  ret_code = NaClAddThread(app, NULL);
  ASSERT_EQ(1, ret_code);
  ASSERT_EQ(2, app->num_threads);

  // no thread at pos 1 -> pos 1 is available
  ret_code = NaClAddThread(app, appt);
  ASSERT_EQ(1, ret_code);
  ASSERT_EQ(3, app->num_threads);

  NaClRemoveThread(app, 0);
  ASSERT_EQ(2, app->num_threads);
}
<|endoftext|>


<commit_before>#include "fileorganiserwidget.h"

#include <QPaintEvent>
#include <QStandardItemModel>

FileOrganiserWidget::FileOrganiserWidget(const QString &pName,
                                         QWidget *pParent) :
    QTreeView(pParent),
    CommonWidget(pName, this, pParent)
{
    // Create an instance of the data model that we want to view

    mDataModel = new QStandardItemModel;

    // Set some properties for the file organiser widget itself

#ifdef Q_WS_MAC
    setAttribute(Qt::WA_MacShowFocusRect, 0);
    // Note: the above removes the focus border since it messes up our toolbar
#endif
    setEditTriggers(QAbstractItemView::EditKeyPressed);
    setHeaderHidden(true);
    setModel(mDataModel);
    setSelectionMode(QAbstractItemView::ExtendedSelection);
    setUniformRowHeights(true);
}

QSize FileOrganiserWidget::sizeHint() const
{
    // Suggest a default size for the file organiser widget
    // Note: this is critical if we want a docked widget, with a file organiser
    //       widget on it, to have a decent size when docked to the main window

    return defaultSize(0.15);
}

QString FileOrganiserWidget::newFolderName(QStandardItem *pFolderItem)
{
    // Come up with the name for a new folder which is to be under pFolderItem

    static const QString baseFolderName = "New Folder";

    if (!pFolderItem->rowCount()) {
        // pFolderItem doesn't have any sub-folder items, so we can use our base
        // folder name

        return baseFolderName;
    } else {
        // pFolderItem has one or more sub-folder items, so we need to come up
        // with a name for the new folder that is not already in use which means
        // retrieving the name of all the sub-folder items

        QStringList subFolderNames;

        for (int i = 0; i < pFolderItem->rowCount(); ++i)
            subFolderNames.append(pFolderItem->child(i)->text());

        static const QString templateFolderName = baseFolderName+" (%1)";
        int folderNb = 1;
        QString folderName;

        do {
            folderName = templateFolderName.arg(++folderNb);
        } while(subFolderNames.contains(folderName));

        return folderName;
    }
}

bool FileOrganiserWidget::newFolder()
{
    // Create a folder item under the current one or root item, if no folder
    // item is currently selected

    QModelIndexList itemsList = selectionModel()->selectedIndexes();
    int nbOfSelectedItems = itemsList.count();

    if (nbOfSelectedItems <= 1) {
        // Either no or one folder item is currently selected, so create the new
        // folder item under the root item or the existing folder item,
        // respecitvely

        QStandardItem *crtFolderItem = !nbOfSelectedItems?
                                           mDataModel->invisibleRootItem():
                                           mDataModel->itemFromIndex(itemsList.at(0));
        QStandardItem *newFolderItem = new QStandardItem(QIcon(":folder"), newFolderName(crtFolderItem));

        crtFolderItem->appendRow(newFolderItem);

        return true;
    } else {
        // Several folder items are selected, so...
        // Note: we should never come here (i.e. the caller to this function
        //       should ensure that a folder can be created before calling this
        //       function), but it's better to be safe than sorry

        return false;
    }
}

bool FileOrganiserWidget::deleteItems()
{
    // Remove all the selected items

    QModelIndexList itemsList = selectionModel()->selectedIndexes();

    if (itemsList.isEmpty()) {
        // Nothing to delete, so...
        // Note: we should never come here (i.e. the caller to this function
        //       should ensure that a folder can be created before calling this
        //       function), but it's better to be safe than sorry

        return false;
    } else {
        // There are some items to delete, so delete them one by one, making
        // sure we update our list of items (this is because the row value of
        // the remaining selected items may become different after deleting an
        // item)

        while(!itemsList.isEmpty()) {
            mDataModel->removeRow(itemsList.first().row(),
                                  itemsList.first().parent());

            itemsList = selectionModel()->selectedIndexes();
        }

        return true;
    }
}
<commit_msg>File organiser window: allow the editing of a newly added folder item.<commit_after>#include "fileorganiserwidget.h"

#include <QPaintEvent>
#include <QStandardItemModel>

FileOrganiserWidget::FileOrganiserWidget(const QString &pName,
                                         QWidget *pParent) :
    QTreeView(pParent),
    CommonWidget(pName, this, pParent)
{
    // Create an instance of the data model that we want to view

    mDataModel = new QStandardItemModel;

    // Set some properties for the file organiser widget itself

#ifdef Q_WS_MAC
    setAttribute(Qt::WA_MacShowFocusRect, 0);
    // Note: the above removes the focus border since it messes up our toolbar
#endif
    setEditTriggers(QAbstractItemView::EditKeyPressed);
    setHeaderHidden(true);
    setModel(mDataModel);
    setSelectionMode(QAbstractItemView::ExtendedSelection);
    setUniformRowHeights(true);
}

QSize FileOrganiserWidget::sizeHint() const
{
    // Suggest a default size for the file organiser widget
    // Note: this is critical if we want a docked widget, with a file organiser
    //       widget on it, to have a decent size when docked to the main window

    return defaultSize(0.15);
}

QString FileOrganiserWidget::newFolderName(QStandardItem *pFolderItem)
{
    // Come up with the name for a new folder which is to be under pFolderItem

    static const QString baseFolderName = "New Folder";

    if (!pFolderItem->rowCount()) {
        // pFolderItem doesn't have any sub-folder items, so we can use our base
        // folder name

        return baseFolderName;
    } else {
        // pFolderItem has one or more sub-folder items, so we need to come up
        // with a name for the new folder that is not already in use which means
        // retrieving the name of all the sub-folder items

        QStringList subFolderNames;

        for (int i = 0; i < pFolderItem->rowCount(); ++i)
            subFolderNames.append(pFolderItem->child(i)->text());

        static const QString templateFolderName = baseFolderName+" (%1)";
        int folderNb = 1;
        QString folderName;

        do {
            folderName = templateFolderName.arg(++folderNb);
        } while(subFolderNames.contains(folderName));

        return folderName;
    }
}

bool FileOrganiserWidget::newFolder()
{
    // Create a folder item under the current one or root item, if no folder
    // item is currently selected

    QModelIndexList itemsList = selectionModel()->selectedIndexes();
    int nbOfSelectedItems = itemsList.count();

    if (nbOfSelectedItems <= 1) {
        // Either no or one folder item is currently selected, so create the new
        // folder item under the root item or the existing folder item,
        // respecitvely

        QStandardItem *crtFolderItem = !nbOfSelectedItems?
                                           mDataModel->invisibleRootItem():
                                           mDataModel->itemFromIndex(itemsList.at(0));
        QStandardItem *newFolderItem = new QStandardItem(QIcon(":folder"), newFolderName(crtFolderItem));

        crtFolderItem->appendRow(newFolderItem);

        // Expand the current index (so that we can see the new folder)
        // Note: this is only relevant in the case of a folder item being
        //       currently selected

        if (nbOfSelectedItems == 1)
            setExpanded(currentIndex(), true);

        // Offer the user to edit the newly added folder item

        edit(newFolderItem->index());

        return true;
    } else {
        // Several folder items are selected, so...
        // Note: we should never come here (i.e. the caller to this function
        //       should ensure that a folder can be created before calling this
        //       function), but it's better to be safe than sorry

        return false;
    }
}

bool FileOrganiserWidget::deleteItems()
{
    // Remove all the selected items

    QModelIndexList itemsList = selectionModel()->selectedIndexes();

    if (itemsList.isEmpty()) {
        // Nothing to delete, so...
        // Note: we should never come here (i.e. the caller to this function
        //       should ensure that a folder can be created before calling this
        //       function), but it's better to be safe than sorry

        return false;
    } else {
        // There are some items to delete, so delete them one by one, making
        // sure we update our list of items (this is because the row value of
        // the remaining selected items may become different after deleting an
        // item)

        while(!itemsList.isEmpty()) {
            mDataModel->removeRow(itemsList.first().row(),
                                  itemsList.first().parent());

            itemsList = selectionModel()->selectedIndexes();
        }

        return true;
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>

#include <zombye/core/game.hpp>

int main() {
    std::cout << "init zombye" << std::endl;

    zombye::game game("project-zombye", 800, 600);

    game.run();

    return 0;
}<commit_msg>add os info to main<commit_after>#include <iostream>
#include <string>

#include <zombye/core/game.hpp>
#include <zombye/utils/os.h>

int main() {
    std::cout << "init zombye with OS: " << OS_NAME << std::endl;

    zombye::game game("project-zombye", 800, 600);

    game.run();

    return 0;
}<|endoftext|>