text:
//  (C) Copyright John Maddock 2021.
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//
// This test verifies that the limits we use in the numerical approximations to erf/erc
// are indeed correct.  The values tested must of course match the values used in erf.hpp.
// See https://github.com/boostorg/math/issues/710
//

#define BOOST_TEST_MODULE erf_limits

#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/math/special_functions/erf.hpp>
#include <boost/test/included/unit_test.hpp>

#include <cfloat>

BOOST_AUTO_TEST_CASE(limits_53_digits)
{
   double arg = 5.93f;

   double t = (double)boost::math::erf(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 1.0);

   arg = 5.9;
   BOOST_CHECK_LT(boost::math::erf(arg), 1.0);

   arg = 28;
   t = (double)boost::math::erfc(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 0.0);

   arg = 27.2;

   BOOST_CHECK_GT(boost::math::erfc(arg), 0.0);
}

BOOST_AUTO_TEST_CASE(limits_64_digits)
{
   float arg = 6.6f;

   boost::multiprecision::cpp_bin_float_double_extended t = (boost::multiprecision::cpp_bin_float_double_extended)boost::math::erf(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 1.0);

#if (LDBL_MANT_DIG == 64) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
   arg = 6.5;
   BOOST_CHECK_LT(boost::math::erf(static_cast<long double>(arg)), 1.0L);
#endif
   arg = 110;
   t = (boost::multiprecision::cpp_bin_float_double_extended)boost::math::erfc(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 0.0);

#if (LDBL_MANT_DIG == 64) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
   arg = 106.5;
   BOOST_CHECK_GT(boost::math::erfc(static_cast<long double>(arg)), 0.0L);
#endif
}

BOOST_AUTO_TEST_CASE(limits_113_digits)
{
   //
   // This limit is not actually used in the code, logged here for future reference...
   //
   float arg = 8.8f;

   boost::multiprecision::cpp_bin_float_quad t = (boost::multiprecision::cpp_bin_float_quad)boost::math::erf(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 1.0);

   arg = 110;
   t = (boost::multiprecision::cpp_bin_float_quad)boost::math::erfc(boost::multiprecision::cpp_bin_float_50(arg));
   BOOST_CHECK_EQUAL(t, 0.0);
}


text:
/**
	curl-asio: wrapper for integrating libcurl with boost.asio applications
	Copyright (c) 2013 Oliver Kuckertz <oliver.kuckertz@mologie.de>
	See COPYING for license information.

	Constructs libcurl string lists
*/

#include <boost/asio.hpp>
#include <curl-asio/error_code.h>
#include <curl-asio/share.h>

using namespace curl;

share::share()
{
	initref_ = initialization::ensure_initialization();
	handle_ = native::curl_share_init();

	if (!handle_)
	{
		throw std::bad_alloc();
	}

	set_lock_function(&share::lock);
	set_unlock_function(&share::unlock);
	set_user_data(this);
}

share::~share()
{
	if (handle_)
	{
		native::curl_share_cleanup(handle_);
		handle_ = 0;
	}
}

void share::set_share_cookies(bool enabled)
{
	boost::system::error_code ec(native::curl_share_setopt(handle_, enabled ? native::CURLSHOPT_SHARE : native::CURLSHOPT_UNSHARE, native::CURL_LOCK_DATA_COOKIE));
	boost::asio::detail::throw_error(ec);
}

void share::set_share_dns(bool enabled)
{
	boost::system::error_code ec(native::curl_share_setopt(handle_, enabled ? native::CURLSHOPT_SHARE : native::CURLSHOPT_UNSHARE, native::CURL_LOCK_DATA_DNS));
	boost::asio::detail::throw_error(ec);
}

void share::set_share_ssl_session(bool enabled)
{
	boost::system::error_code ec(native::curl_share_setopt(handle_, enabled ? native::CURLSHOPT_SHARE : native::CURLSHOPT_UNSHARE, native::CURL_LOCK_DATA_SSL_SESSION));
	boost::asio::detail::throw_error(ec);
}

void share::set_lock_function(lock_function_t lock_function)
{
	boost::system::error_code ec(native::curl_share_setopt(handle_, native::CURLSHOPT_LOCKFUNC, lock_function));
	boost::asio::detail::throw_error(ec);
}

void share::set_unlock_function(unlock_function_t unlock_function)
{
	boost::system::error_code ec(native::curl_share_setopt(handle_, native::CURLSHOPT_UNLOCKFUNC, unlock_function));
	boost::asio::detail::throw_error(ec);
}

void share::set_user_data(void* user_data)
{
	boost::system::error_code ec(native::curl_share_setopt(handle_, native::CURLSHOPT_USERDATA, user_data));
	boost::asio::detail::throw_error(ec);
}

void share::lock(native::CURL* handle, native::curl_lock_data data, native::curl_lock_access access, void* userptr)
{
	share* self = static_cast<share*>(userptr);
	self->mutex_.lock();
}

void share::unlock(native::CURL* handle, native::curl_lock_data data, void* userptr)
{
	share* self = static_cast<share*>(userptr);
	self->mutex_.unlock();
}

ext: cpp

max_stars_repo_name: QuentinFiard/curl-asio

max_stars_repo_licenses: curl MIT

max_issues_repo_name: QuentinFiard/curl-asio

max_issues_repo_licenses: curl MIT

max_forks_repo_name: QuentinFiard/curl-asio

max_forks_repo_licenses: curl MIT


text:
//
//  Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_LOCALE_IMPL_STD_ALL_GENERATOR_HPP
#define BOOST_LOCALE_IMPL_STD_ALL_GENERATOR_HPP

#include <boost/locale/generator.hpp>
#include <vector>

namespace boost
{
namespace locale
{
namespace impl_std
{
typedef enum
{
    utf8_none,
    utf8_native,
    utf8_native_with_wide,
    utf8_from_wide
} utf8_support;

std::locale create_convert(std::locale const& in,
                           std::string const& locale_name,
                           character_facet_type type,
                           utf8_support utf = utf8_none);

std::locale create_collate(std::locale const& in,
                           std::string const& locale_name,
                           character_facet_type type,
                           utf8_support utf = utf8_none);

std::locale create_formatting(std::locale const& in,
                              std::string const& locale_name,
                              character_facet_type type,
                              utf8_support utf = utf8_none);

std::locale create_parsing(std::locale const& in,
                           std::string const& locale_name,
                           character_facet_type type,
                           utf8_support utf = utf8_none);

std::locale create_codecvt(std::locale const& in,
                           std::string const& locale_name,
                           character_facet_type type,
                           utf8_support utf = utf8_none);

} // namespace impl_std
} // namespace locale
} // namespace boost

#endif
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4

ext: hpp

max_stars_repo_name: sotaoverride/backup

max_issues_repo_name: sotaoverride/backup

max_forks_repo_name: sotaoverride/backup


text:
/*
 * Copyright 2011-present Facebook, Inc.
 *
 * 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.
 */

//
// Author: andrei.alexandrescu@fb.com

#include <folly/FBString.h>

#include <atomic>
#include <cstdlib>
#include <iomanip>
#include <list>
#include <random>
#include <sstream>

#include <boost/algorithm/string.hpp>

#include <folly/Conv.h>
#include <folly/Portability.h>
#include <folly/Random.h>
#include <folly/Utility.h>
#include <folly/container/Foreach.h>
#include <folly/portability/GTest.h>
#include <folly/test/TestUtils.h>

using namespace std;
using namespace folly;

namespace {

static const int seed = folly::randomNumberSeed();
using RandomT = std::mt19937;
static RandomT rng(seed);
static const size_t maxString = 100;
static const bool avoidAliasing = true;

template <class Integral1, class Integral2>
Integral2 random(Integral1 low, Integral2 up) {
  std::uniform_int_distribution<> range(low, up);
  return range(rng);
}

template <class String>
void randomString(String* toFill, unsigned int maxSize = 1000) {
  assert(toFill);
  toFill->resize(random(0, maxSize));
  FOR_EACH (i, *toFill) { *i = random('a', 'z'); }
}

template <class String, class Integral>
void Num2String(String& str, Integral n) {
  std::string tmp = folly::to<std::string>(n);
  str = String(tmp.begin(), tmp.end());
}

std::list<char> RandomList(unsigned int maxSize) {
  std::list<char> lst(random(0u, maxSize));
  std::list<char>::iterator i = lst.begin();
  for (; i != lst.end(); ++i) {
    *i = random('a', 'z');
  }
  return lst;
}
} // namespace

////////////////////////////////////////////////////////////////////////////////
// Tests begin here
////////////////////////////////////////////////////////////////////////////////

template <class String>
void clause11_21_4_2_a(String& test) {
  test.String::~String();
  new (&test) String();
}
template <class String>
void clause11_21_4_2_b(String& test) {
  String test2(test);
  assert(test2 == test);
}
template <class String>
void clause11_21_4_2_c(String& test) {
  // Test move constructor. There is a more specialized test, see
  // TEST(FBString, testMoveCtor)
  String donor(test);
  String test2(std::move(donor));
  EXPECT_EQ(test2, test);
  // Technically not required, but all implementations that actually
  // support move will move large strings. Make a guess for 128 as the
  // maximum small string optimization that's reasonable.
  EXPECT_LE(donor.size(), 128);
}
template <class String>
void clause11_21_4_2_d(String& test) {
  // Copy constructor with position and length
  const size_t pos = random(0, test.size());
  String s(
      test,
      pos,
      random(0, 9) ? random(0, (size_t)(test.size() - pos))
                   : String::npos); // test for npos, too, in 10% of the cases
  test = s;
}
template <class String>
void clause11_21_4_2_e(String& test) {
  // Constructor from char*, size_t
  const size_t pos = random(0, test.size()), n = random(0, test.size() - pos);
  String before(test.data(), test.size());
  String s(test.c_str() + pos, n);
  String after(test.data(), test.size());
  EXPECT_EQ(before, after);
  test.swap(s);
}
template <class String>
void clause11_21_4_2_f(String& test) {
  // Constructor from char*
  const size_t pos = random(0, test.size());
  String before(test.data(), test.size());
  String s(test.c_str() + pos);
  String after(test.data(), test.size());
  EXPECT_EQ(before, after);
  test.swap(s);
}
template <class String>
void clause11_21_4_2_g(String& test) {
  // Constructor from size_t, char
  const size_t n = random(0, test.size());
  const auto c = test.front();
  test = String(n, c);
}
template <class String>
void clause11_21_4_2_h(String& test) {
  // Constructors from various iterator pairs
  // Constructor from char*, char*
  String s1(test.begin(), test.end());
  EXPECT_EQ(test, s1);
  String s2(test.data(), test.data() + test.size());
  EXPECT_EQ(test, s2);
  // Constructor from other iterators
  std::list<char> lst;
  for (auto c : test) {
    lst.push_back(c);
  }
  String s3(lst.begin(), lst.end());
  EXPECT_EQ(test, s3);
  // Constructor from wchar_t iterators
  std::list<wchar_t> lst1;
  for (auto c : test) {
    lst1.push_back(c);
  }
  String s4(lst1.begin(), lst1.end());
  EXPECT_EQ(test, s4);
  // Constructor from wchar_t pointers
  wchar_t t[20];
  t[0] = 'a';
  t[1] = 'b';
  fbstring s5(t, t + 2);
  EXPECT_EQ("ab", s5);
}
template <class String>
void clause11_21_4_2_i(String& test) {
  // From initializer_list<char>
  std::initializer_list<typename String::value_type> il = {
      'h', 'e', 'l', 'l', 'o'};
  String s(il);
  test.swap(s);
}
template <class String>
void clause11_21_4_2_j(String& test) {
  // Assignment from const String&
  auto size = random(0, 2000);
  String s(size, '\0');
  EXPECT_EQ(s.size(), size);
  FOR_EACH_RANGE (i, 0, s.size()) { s[i] = random('a', 'z'); }
  test = s;
}
template <class String>
void clause11_21_4_2_k(String& test) {
  // Assignment from String&&
  auto size = random(0, 2000);
  String s(size, '\0');
  EXPECT_EQ(s.size(), size);
  FOR_EACH_RANGE (i, 0, s.size()) { s[i] = random('a', 'z'); }
  test = std::move(s);
  if (std::is_same<String, fbstring>::value) {
    EXPECT_LE(s.size(), 128);
  }
}
template <class String>
void clause11_21_4_2_l(String& test) {
  // Assignment from char*
  String s(random(0, 1000), '\0');
  size_t i = 0;
  for (; i != s.size(); ++i) {
    s[i] = random('a', 'z');
  }
  test = s.c_str();
}
template <class String>
void clause11_21_4_2_lprime(String& test) {
  // Aliased assign
  const size_t pos = random(0, test.size());
  if (avoidAliasing) {
    test = String(test.c_str() + pos);
  } else {
    test = test.c_str() + pos;
  }
}
template <class String>
void clause11_21_4_2_m(String& test) {
  // Assignment from char
  using value_type = typename String::value_type;
  test = random(static_cast<value_type>('a'), static_cast<value_type>('z'));
}
template <class String>
void clause11_21_4_2_n(String& test) {
  // Assignment from initializer_list<char>
  initializer_list<typename String::value_type> il = {'h', 'e', 'l', 'l', 'o'};
  test = il;
}

template <class String>
void clause11_21_4_3(String& test) {
  // Iterators. The code below should leave test unchanged
  EXPECT_EQ(test.size(), test.end() - test.begin());
  EXPECT_EQ(test.size(), test.rend() - test.rbegin());
  EXPECT_EQ(test.size(), test.cend() - test.cbegin());
  EXPECT_EQ(test.size(), test.crend() - test.crbegin());

  auto s = test.size();
  test.resize(test.end() - test.begin());
  EXPECT_EQ(s, test.size());
  test.resize(test.rend() - test.rbegin());
  EXPECT_EQ(s, test.size());
}

template <class String>
void clause11_21_4_4(String& test) {
  // exercise capacity, size, max_size
  EXPECT_EQ(test.size(), test.length());
  EXPECT_LE(test.size(), test.max_size());
  EXPECT_LE(test.capacity(), test.max_size());
  EXPECT_LE(test.size(), test.capacity());

  // exercise shrink_to_fit. Nonbinding request so we can't really do
  // much beyond calling it.
  auto copy = test;
  copy.reserve(copy.capacity() * 3);
  copy.shrink_to_fit();
  EXPECT_EQ(copy, test);

  // exercise empty
  string empty("empty");
  string notempty("not empty");
  if (test.empty()) {
    test = String(empty.begin(), empty.end());
  } else {
    test = String(notempty.begin(), notempty.end());
  }
}

template <class String>
void clause11_21_4_5(String& test) {
  // exercise element access
  if (!test.empty()) {
    EXPECT_EQ(test[0], test.front());
    EXPECT_EQ(test[test.size() - 1], test.back());
    auto const i = random(0, test.size() - 1);
    EXPECT_EQ(test[i], test.at(i));
    test = test[i];
  }

  EXPECT_THROW(test.at(test.size()), std::out_of_range);
  EXPECT_THROW(as_const(test).at(test.size()), std::out_of_range);
}

template <class String>
void clause11_21_4_6_1(String& test) {
  // 21.3.5 modifiers (+=)
  String test1;
  randomString(&test1);
  assert(
      test1.size() ==
      char_traits<typename String::value_type>::length(test1.c_str()));
  auto len = test.size();
  test += test1;
  EXPECT_EQ(test.size(), test1.size() + len);
  FOR_EACH_RANGE (i, 0, test1.size()) { EXPECT_EQ(test[len + i], test1[i]); }
  // aliasing modifiers
  String test2 = test;
  auto dt = test2.data();
  auto sz = test.c_str();
  len = test.size();
  EXPECT_EQ(memcmp(sz, dt, len), 0);
  String copy(test.data(), test.size());
  EXPECT_EQ(
      char_traits<typename String::value_type>::length(test.c_str()), len);
  test += test;
  // test.append(test);
  EXPECT_EQ(test.size(), 2 * len);
  EXPECT_EQ(
      char_traits<typename String::value_type>::length(test.c_str()), 2 * len);
  FOR_EACH_RANGE (i, 0, len) {
    EXPECT_EQ(test[i], copy[i]);
    EXPECT_EQ(test[i], test[len + i]);
  }
  len = test.size();
  EXPECT_EQ(
      char_traits<typename String::value_type>::length(test.c_str()), len);
  // more aliasing
  auto const pos = random(0, test.size());
  EXPECT_EQ(
      char_traits<typename String::value_type>::length(test.c_str() + pos),
      len - pos);
  if (avoidAliasing) {
    String addMe(test.c_str() + pos);
    EXPECT_EQ(addMe.size(), len - pos);
    test += addMe;
  } else {
    test += test.c_str() + pos;
  }
  EXPECT_EQ(test.size(), 2 * len - pos);
  // single char
  len = test.size();
  test += random('a', 'z');
  EXPECT_EQ(test.size(), len + 1);
  // initializer_list
  initializer_list<typename String::value_type> il{'a', 'b', 'c'};
  test += il;
}

template <class String>
void clause11_21_4_6_2(String& test) {
  // 21.3.5 modifiers (append, push_back)
  String s;

  // Test with a small string first
  char c = random('a', 'z');
  s.push_back(c);
  EXPECT_EQ(s[s.size() - 1], c);
  EXPECT_EQ(s.size(), 1);
  s.resize(s.size() - 1);

  randomString(&s, maxString);
  test.append(s);
  randomString(&s, maxString);
  test.append(s, random(0, s.size()), random(0, maxString));
  randomString(&s, maxString);
  test.append(s.c_str(), random(0, s.size()));
  randomString(&s, maxString);
  test.append(s.c_str());
  test.append(random(0, maxString), random('a', 'z'));
  std::list<char> lst(RandomList(maxString));
  test.append(lst.begin(), lst.end());
  c = random('a', 'z');
  test.push_back(c);
  EXPECT_EQ(test[test.size() - 1], c);
  // initializer_list
  initializer_list<typename String::value_type> il{'a', 'b', 'c'};
  test.append(il);
}

template <class String>
void clause11_21_4_6_3_a(String& test) {
  // assign
  String s;
  randomString(&s);
  test.assign(s);
  EXPECT_EQ(test, s);
  // move assign
  test.assign(std::move(s));
  if (std::is_same<String, fbstring>::value) {
    EXPECT_LE(s.size(), 128);
  }
}

template <class String>
void clause11_21_4_6_3_b(String& test) {
  // assign
  String s;
  randomString(&s, maxString);
  test.assign(s, random(0, s.size()), random(0, maxString));
}

template <class String>
void clause11_21_4_6_3_c(String& test) {
  // assign
  String s;
  randomString(&s, maxString);
  test.assign(s.c_str(), random(0, s.size()));
}

template <class String>
void clause11_21_4_6_3_d(String& test) {
  // assign
  String s;
  randomString(&s, maxString);
  test.assign(s.c_str());
}

template <class String>
void clause11_21_4_6_3_e(String& test) {
  // assign
  String s;
  randomString(&s, maxString);
  test.assign(random(0, maxString), random('a', 'z'));
}

template <class String>
void clause11_21_4_6_3_f(String& test) {
  // assign from bidirectional iterator
  std::list<char> lst(RandomList(maxString));
  test.assign(lst.begin(), lst.end());
}

template <class String>
void clause11_21_4_6_3_g(String& test) {
  // assign from aliased source
  test.assign(test);
}

template <class String>
void clause11_21_4_6_3_h(String& test) {
  // assign from aliased source
  test.assign(test, random(0, test.size()), random(0, maxString));
}

template <class String>
void clause11_21_4_6_3_i(String& test) {
  // assign from aliased source
  test.assign(test.c_str(), random(0, test.size()));
}

template <class String>
void clause11_21_4_6_3_j(String& test) {
  // assign from aliased source
  test.assign(test.c_str());
}

template <class String>
void clause11_21_4_6_3_k(String& test) {
  // assign from initializer_list
  initializer_list<typename String::value_type> il{'a', 'b', 'c'};
  test.assign(il);
}

template <class String>
void clause11_21_4_6_4(String& test) {
  // insert
  String s;
  randomString(&s, maxString);
  test.insert(random(0, test.size()), s);
  randomString(&s, maxString);
  test.insert(
      random(0, test.size()), s, random(0, s.size()), random(0, maxString));
  randomString(&s, maxString);
  test.insert(random(0, test.size()), s.c_str(), random(0, s.size()));
  randomString(&s, maxString);
  test.insert(random(0, test.size()), s.c_str());
  test.insert(random(0, test.size()), random(0, maxString), random('a', 'z'));
  typename String::size_type pos = random(0, test.size());
  typename String::iterator res =
      test.insert(test.begin() + pos, random('a', 'z'));
  EXPECT_EQ(res - test.begin(), pos);
  std::list<char> lst(RandomList(maxString));
  pos = random(0, test.size());
  // Uncomment below to see a bug in gcc
  /*res = */ test.insert(test.begin() + pos, lst.begin(), lst.end());
  // insert from initializer_list
  initializer_list<typename String::value_type> il{'a', 'b', 'c'};
  pos = random(0, test.size());
  // Uncomment below to see a bug in gcc
  /*res = */ test.insert(test.begin() + pos, il);

  // Test with actual input iterators
  stringstream ss;
  ss << "hello cruel world";
  auto i = istream_iterator<char>(ss);
  test.insert(test.begin(), i, istream_iterator<char>());
}

template <class String>
void clause11_21_4_6_5(String& test) {
  // erase and pop_back
  if (!test.empty()) {
    test.erase(random(0, test.size()), random(0, maxString));
  }
  if (!test.empty()) {
    // TODO: is erase(end()) allowed?
    test.erase(test.begin() + random(0, test.size() - 1));
  }
  if (!test.empty()) {
    auto const i = test.begin() + random(0, test.size());
    if (i != test.end()) {
      test.erase(i, i + random(0, size_t(test.end() - i)));
    }
  }
  if (!test.empty()) {
    // Can't test pop_back with std::string, doesn't support it yet.
    // test.pop_back();
  }
}

template <class String>
void clause11_21_4_6_6(String& test) {
  auto pos = random(0, test.size());
  if (avoidAliasing) {
    test.replace(pos, random(0, test.size() - pos), String(test));
  } else {
    test.replace(pos, random(0, test.size() - pos), test);
  }
  pos = random(0, test.size());
  String s;
  randomString(&s, maxString);
  test.replace(pos, pos + random(0, test.size() - pos), s);
  auto pos1 = random(0, test.size());
  auto pos2 = random(0, test.size());
  if (avoidAliasing) {
    test.replace(
        pos1,
        pos1 + random(0, test.size() - pos1),
        String(test),
        pos2,
        pos2 + random(0, test.size() - pos2));
  } else {
    test.replace(
        pos1,
        pos1 + random(0, test.size() - pos1),
        test,
        pos2,
        pos2 + random(0, test.size() - pos2));
  }
  pos1 = random(0, test.size());
  String str;
  randomString(&str, maxString);
  pos2 = random(0, str.size());
  test.replace(
      pos1,
      pos1 + random(0, test.size() - pos1),
      str,
      pos2,
      pos2 + random(0, str.size() - pos2));
  pos = random(0, test.size());
  if (avoidAliasing) {
    test.replace(
        pos, random(0, test.size() - pos), String(test).c_str(), test.size());
  } else {
    test.replace(pos, random(0, test.size() - pos), test.c_str(), test.size());
  }
  pos = random(0, test.size());
  randomString(&str, maxString);
  test.replace(
      pos, pos + random(0, test.size() - pos), str.c_str(), str.size());
  pos = random(0, test.size());
  randomString(&str, maxString);
  test.replace(pos, pos + random(0, test.size() - pos), str.c_str());
  pos = random(0, test.size());
  test.replace(
      pos,
      random(0, test.size() - pos),
      random(0, maxString),
      random('a', 'z'));
  pos = random(0, test.size());
  if (avoidAliasing) {
    auto newString = String(test);
    test.replace(
        test.begin() + pos,
        test.begin() + pos + random(0, test.size() - pos),
        newString);
  } else {
    test.replace(
        test.begin() + pos,
        test.begin() + pos + random(0, test.size() - pos),
        test);
  }
  pos = random(0, test.size());
  if (avoidAliasing) {
    auto newString = String(test);
    test.replace(
        test.begin() + pos,
        test.begin() + pos + random(0, test.size() - pos),
        newString.c_str(),
        test.size() - random(0, test.size()));
  } else {
    test.replace(
        test.begin() + pos,
        test.begin() + pos + random(0, test.size() - pos),
        test.c_str(),
        test.size() - random(0, test.size()));
  }
  pos = random(0, test.size());
  auto const n = random(0, test.size() - pos);
  typename String::iterator b = test.begin();
  String str1;
  randomString(&str1, maxString);
  const String& str3 = str1;
  const typename String::value_type* ss = str3.c_str();
  test.replace(b + pos, b + pos + n, ss);
  pos = random(0, test.size());
  test.replace(
      test.begin() + pos,
      test.begin() + pos + random(0, test.size() - pos),
      random(0, maxString),
      random('a', 'z'));
}

template <class String>
void clause11_21_4_6_7(String& test) {
  std::vector<typename String::value_type> vec(random(0, maxString));
  if (vec.empty()) {
    return;
  }
  test.copy(vec.data(), vec.size(), random(0, test.size()));
}

template <class String>
void clause11_21_4_6_8(String& test) {
  String s;
  randomString(&s, maxString);
  s.swap(test);
}

template <class String>
void clause11_21_4_7_1(String& test) {
  // 21.3.6 string operations
  // exercise c_str() and data()
  assert(test.c_str() == test.data());
  // exercise get_allocator()
  String s;
  randomString(&s, maxString);
  DCHECK(test.get_allocator() == s.get_allocator());
}

template <class String>
void clause11_21_4_7_2_a(String& test) {
  String str = test.substr(random(0, test.size()), random(0, test.size()));
  Num2String(test, test.find(str, random(0, test.size())));
}

template <class String>
void clause11_21_4_7_2_a1(String& test) {
  String str =
      String(test).substr(random(0, test.size()), random(0, test.size()));
  Num2String(test, test.find(str, random(0, test.size())));
}

template <class String>
void clause11_21_4_7_2_a2(String& test) {
  auto const& cTest = test;
  String str = cTest.substr(random(0, test.size()), random(0, test.size()));
  Num2String(test, test.find(str, random(0, test.size())));
}

template <class String>
void clause11_21_4_7_2_b(String& test) {
  auto from = random(0, test.size());
  auto length = random(0, test.size() - from);
  String str = test.substr(from, length);
  Num2String(
      test,
      test.find(str.c_str(), random(0, test.size()), random(0, str.size())));
}

template <class String>
void clause11_21_4_7_2_b1(String& test) {
  auto from = random(0, test.size());
  auto length = random(0, test.size() - from);
  String str = String(test).substr(from, length);
  Num2String(
      test,
      test.find(str.c_str(), random(0, test.size()), random(0, str.size())));
}

template <class String>
void clause11_21_4_7_2_b2(String& test) {
  auto from = random(0, test.size());
  auto length = random(0, test.size() - from);
  const auto& cTest = test;
  String str = cTest.substr(from, length);
  Num2String(
      test,
      test.find(str.c_str(), random(0, test.size()), random(0, str.size())));
}

template <class String>
void clause11_21_4_7_2_c(String& test) {
  String str = test.substr(random(0, test.size()), random(0, test.size()));
  Num2String(test, test.find(str.c_str(), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_2_c1(String& test) {
  String str =
      String(test).substr(random(0, test.size()), random(0, test.size()));
  Num2String(test, test.find(str.c_str(), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_2_c2(String& test) {
  const auto& cTest = test;
  String str = cTest.substr(random(0, test.size()), random(0, test.size()));
  Num2String(test, test.find(str.c_str(), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_2_d(String& test) {
  Num2String(test, test.find(random('a', 'z'), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_3_a(String& test) {
  String str = test.substr(random(0, test.size()), random(0, test.size()));
  Num2String(test, test.rfind(str, random(0, test.size())));
}

template <class String>
void clause11_21_4_7_3_b(String& test) {
  String str = test.substr(random(0, test.size()), random(0, test.size()));
  Num2String(
      test,
      test.rfind(str.c_str(), random(0, test.size()), random(0, str.size())));
}

template <class String>
void clause11_21_4_7_3_c(String& test) {
  String str = test.substr(random(0, test.size()), random(0, test.size()));
  Num2String(test, test.rfind(str.c_str(), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_3_d(String& test) {
  Num2String(test, test.rfind(random('a', 'z'), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_4_a(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(test, test.find_first_of(str, random(0, test.size())));
}

template <class String>
void clause11_21_4_7_4_b(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(
      test,
      test.find_first_of(
          str.c_str(), random(0, test.size()), random(0, str.size())));
}

template <class String>
void clause11_21_4_7_4_c(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(test, test.find_first_of(str.c_str(), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_4_d(String& test) {
  Num2String(
      test, test.find_first_of(random('a', 'z'), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_5_a(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(test, test.find_last_of(str, random(0, test.size())));
}

template <class String>
void clause11_21_4_7_5_b(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(
      test,
      test.find_last_of(
          str.c_str(), random(0, test.size()), random(0, str.size())));
}

template <class String>
void clause11_21_4_7_5_c(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(test, test.find_last_of(str.c_str(), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_5_d(String& test) {
  Num2String(test, test.find_last_of(random('a', 'z'), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_6_a(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(test, test.find_first_not_of(str, random(0, test.size())));
}

template <class String>
void clause11_21_4_7_6_b(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(
      test,
      test.find_first_not_of(
          str.c_str(), random(0, test.size()), random(0, str.size())));
}

template <class String>
void clause11_21_4_7_6_c(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(test, test.find_first_not_of(str.c_str(), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_6_d(String& test) {
  Num2String(
      test, test.find_first_not_of(random('a', 'z'), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_7_a(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(test, test.find_last_not_of(str, random(0, test.size())));
}

template <class String>
void clause11_21_4_7_7_b(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(
      test,
      test.find_last_not_of(
          str.c_str(), random(0, test.size()), random(0, str.size())));
}

template <class String>
void clause11_21_4_7_7_c(String& test) {
  String str;
  randomString(&str, maxString);
  Num2String(test, test.find_last_not_of(str.c_str(), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_7_d(String& test) {
  Num2String(
      test, test.find_last_not_of(random('a', 'z'), random(0, test.size())));
}

template <class String>
void clause11_21_4_7_8(String& test) {
  test = test.substr(random(0, test.size()), random(0, test.size()));
}

template <class String>
void clause11_21_4_7_9_a(String& test) {
  String s;
  randomString(&s, maxString);
  int tristate = test.compare(s);
  if (tristate > 0) {
    tristate = 1;
  } else if (tristate < 0) {
    tristate = 2;
  }
  Num2String(test, tristate);
}

template <class String>
void clause11_21_4_7_9_b(String& test) {
  String s;
  randomString(&s, maxString);
  int tristate =
      test.compare(random(0, test.size()), random(0, test.size()), s);
  if (tristate > 0) {
    tristate = 1;
  } else if (tristate < 0) {
    tristate = 2;
  }
  Num2String(test, tristate);
}

template <class String>
void clause11_21_4_7_9_c(String& test) {
  String str;
  randomString(&str, maxString);
  int tristate = test.compare(
      random(0, test.size()),
      random(0, test.size()),
      str,
      random(0, str.size()),
      random(0, str.size()));
  if (tristate > 0) {
    tristate = 1;
  } else if (tristate < 0) {
    tristate = 2;
  }
  Num2String(test, tristate);
}

template <class String>
void clause11_21_4_7_9_d(String& test) {
  String s;
  randomString(&s, maxString);
  int tristate = test.compare(s.c_str());
  if (tristate > 0) {
    tristate = 1;
  } else if (tristate < 0) {
    tristate = 2;
  }
  Num2String(test, tristate);
}

template <class String>
void clause11_21_4_7_9_e(String& test) {
  String str;
  randomString(&str, maxString);
  int tristate = test.compare(
      random(0, test.size()),
      random(0, test.size()),
      str.c_str(),
      random(0, str.size()));
  if (tristate > 0) {
    tristate = 1;
  } else if (tristate < 0) {
    tristate = 2;
  }
  Num2String(test, tristate);
}

template <class String>
void clause11_21_4_8_1_a(String& test) {
  String s1;
  randomString(&s1, maxString);
  String s2;
  randomString(&s2, maxString);
  test = s1 + s2;
}

template <class String>
void clause11_21_4_8_1_b(String& test) {
  String s1;
  randomString(&s1, maxString);
  String s2;
  randomString(&s2, maxString);
  test = move(s1) + s2;
}

template <class String>
void clause11_21_4_8_1_c(String& test) {
  String s1;
  randomString(&s1, maxString);
  String s2;
  randomString(&s2, maxString);
  test = s1 + move(s2);
}

template <class String>
void clause11_21_4_8_1_d(String& test) {
  String s1;
  randomString(&s1, maxString);
  String s2;
  randomString(&s2, maxString);
  test = move(s1) + move(s2);
}

template <class String>
void clause11_21_4_8_1_e(String& test) {
  String s;
  randomString(&s, maxString);
  String s1;
  randomString(&s1, maxString);
  test = s.c_str() + s1;
}

template <class String>
void clause11_21_4_8_1_f(String& test) {
  String s;
  randomString(&s, maxString);
  String s1;
  randomString(&s1, maxString);
  test = s.c_str() + move(s1);
}

template <class String>
void clause11_21_4_8_1_g(String& test) {
  String s;
  randomString(&s, maxString);
  test = typename String::value_type(random('a', 'z')) + s;
}

template <class String>
void clause11_21_4_8_1_h(String& test) {
  String s;
  randomString(&s, maxString);
  test = typename String::value_type(random('a', 'z')) + move(s);
}

template <class String>
void clause11_21_4_8_1_i(String& test) {
  String s;
  randomString(&s, maxString);
  String s1;
  randomString(&s1, maxString);
  test = s + s1.c_str();
}

template <class String>
void clause11_21_4_8_1_j(String& test) {
  String s;
  randomString(&s, maxString);
  String s1;
  randomString(&s1, maxString);
  test = move(s) + s1.c_str();
}

template <class String>
void clause11_21_4_8_1_k(String& test) {
  String s;
  randomString(&s, maxString);
  test = s + typename String::value_type(random('a', 'z'));
}

template <class String>
void clause11_21_4_8_1_l(String& test) {
  String s;
  randomString(&s, maxString);
  String s1;
  randomString(&s1, maxString);
  test = move(s) + s1.c_str();
}

// Numbering here is from C++11
template <class String>
void clause11_21_4_8_9_a(String& test) {
  basic_stringstream<typename String::value_type> stst(test.c_str());
  String str;
  while (stst) {
    stst >> str;
    test += str + test;
  }
}

TEST(FBString, testAllClauses) {
  EXPECT_TRUE(1) << "Starting with seed: " << seed;
  std::string r;
  folly::fbstring c;
#if FOLLY_HAVE_WCHAR_SUPPORT
  std::wstring wr;
  folly::basic_fbstring<wchar_t> wc;
#endif
  int count = 0;

  auto l = [&](const char* const clause,
               void (*f_string)(std::string&),
               void (*f_fbstring)(folly::fbstring&),
               void (*f_wfbstring)(folly::basic_fbstring<wchar_t>&)) {
    do {
      if (true) {
      } else {
        EXPECT_TRUE(1) << "Testing clause " << clause;
      }
      randomString(&r);
      c = r;
      EXPECT_EQ(c, r);
#if FOLLY_HAVE_WCHAR_SUPPORT
      wr = std::wstring(r.begin(), r.end());
      wc = folly::basic_fbstring<wchar_t>(wr.c_str());
#endif
      auto localSeed = seed + count;
      rng = RandomT(localSeed);
      f_string(r);
      rng = RandomT(localSeed);
      f_fbstring(c);
      EXPECT_EQ(r, c) << "Lengths: " << r.size() << " vs. " << c.size()
                      << "\nReference: '" << r << "'"
                      << "\nActual:    '" << c.data()[0] << "'";
#if FOLLY_HAVE_WCHAR_SUPPORT
      rng = RandomT(localSeed);
      f_wfbstring(wc);
      int wret = wcslen(wc.c_str());
      auto mbv = std::vector<char>(wret + 1);
      auto mb = mbv.data();
      int ret = wcstombs(mb, wc.c_str(), wret + 1);
      if (ret == wret) {
        mb[wret] = '\0';
      }
      const char* mc = c.c_str();
      std::string one(mb);
      std::string two(mc);
      EXPECT_EQ(one, two);
#endif
    } while (++count % 100 != 0);
  };

#define TEST_CLAUSE(x)             \
  l(#x,                            \
    clause11_##x<std::string>,     \
    clause11_##x<folly::fbstring>, \
    clause11_##x<folly::basic_fbstring<wchar_t>>);

  TEST_CLAUSE(21_4_2_a);
  TEST_CLAUSE(21_4_2_b);
  TEST_CLAUSE(21_4_2_c);
  TEST_CLAUSE(21_4_2_d);
  TEST_CLAUSE(21_4_2_e);
  TEST_CLAUSE(21_4_2_f);
  TEST_CLAUSE(21_4_2_g);
  TEST_CLAUSE(21_4_2_h);
  TEST_CLAUSE(21_4_2_i);
  TEST_CLAUSE(21_4_2_j);
  TEST_CLAUSE(21_4_2_k);
  TEST_CLAUSE(21_4_2_l);
  TEST_CLAUSE(21_4_2_lprime);
  TEST_CLAUSE(21_4_2_m);
  TEST_CLAUSE(21_4_2_n);
  TEST_CLAUSE(21_4_3);
  TEST_CLAUSE(21_4_4);
  TEST_CLAUSE(21_4_5);
  TEST_CLAUSE(21_4_6_1);
  TEST_CLAUSE(21_4_6_2);
  TEST_CLAUSE(21_4_6_3_a);
  TEST_CLAUSE(21_4_6_3_b);
  TEST_CLAUSE(21_4_6_3_c);
  TEST_CLAUSE(21_4_6_3_d);
  TEST_CLAUSE(21_4_6_3_e);
  TEST_CLAUSE(21_4_6_3_f);
  TEST_CLAUSE(21_4_6_3_g);
  TEST_CLAUSE(21_4_6_3_h);
  TEST_CLAUSE(21_4_6_3_i);
  TEST_CLAUSE(21_4_6_3_j);
  TEST_CLAUSE(21_4_6_3_k);
  TEST_CLAUSE(21_4_6_4);
  TEST_CLAUSE(21_4_6_5);
  TEST_CLAUSE(21_4_6_6);
  TEST_CLAUSE(21_4_6_7);
  TEST_CLAUSE(21_4_6_8);
  TEST_CLAUSE(21_4_7_1);

  TEST_CLAUSE(21_4_7_2_a);
  TEST_CLAUSE(21_4_7_2_a1);
  TEST_CLAUSE(21_4_7_2_a2);
  TEST_CLAUSE(21_4_7_2_b);
  TEST_CLAUSE(21_4_7_2_b1);
  TEST_CLAUSE(21_4_7_2_b2);
  TEST_CLAUSE(21_4_7_2_c);
  TEST_CLAUSE(21_4_7_2_c1);
  TEST_CLAUSE(21_4_7_2_c2);
  TEST_CLAUSE(21_4_7_2_d);
  TEST_CLAUSE(21_4_7_3_a);
  TEST_CLAUSE(21_4_7_3_b);
  TEST_CLAUSE(21_4_7_3_c);
  TEST_CLAUSE(21_4_7_3_d);
  TEST_CLAUSE(21_4_7_4_a);
  TEST_CLAUSE(21_4_7_4_b);
  TEST_CLAUSE(21_4_7_4_c);
  TEST_CLAUSE(21_4_7_4_d);
  TEST_CLAUSE(21_4_7_5_a);
  TEST_CLAUSE(21_4_7_5_b);
  TEST_CLAUSE(21_4_7_5_c);
  TEST_CLAUSE(21_4_7_5_d);
  TEST_CLAUSE(21_4_7_6_a);
  TEST_CLAUSE(21_4_7_6_b);
  TEST_CLAUSE(21_4_7_6_c);
  TEST_CLAUSE(21_4_7_6_d);
  TEST_CLAUSE(21_4_7_7_a);
  TEST_CLAUSE(21_4_7_7_b);
  TEST_CLAUSE(21_4_7_7_c);
  TEST_CLAUSE(21_4_7_7_d);
  TEST_CLAUSE(21_4_7_8);
  TEST_CLAUSE(21_4_7_9_a);
  TEST_CLAUSE(21_4_7_9_b);
  TEST_CLAUSE(21_4_7_9_c);
  TEST_CLAUSE(21_4_7_9_d);
  TEST_CLAUSE(21_4_7_9_e);
  TEST_CLAUSE(21_4_8_1_a);
  TEST_CLAUSE(21_4_8_1_b);
  TEST_CLAUSE(21_4_8_1_c);
  TEST_CLAUSE(21_4_8_1_d);
  TEST_CLAUSE(21_4_8_1_e);
  TEST_CLAUSE(21_4_8_1_f);
  TEST_CLAUSE(21_4_8_1_g);
  TEST_CLAUSE(21_4_8_1_h);
  TEST_CLAUSE(21_4_8_1_i);
  TEST_CLAUSE(21_4_8_1_j);
  TEST_CLAUSE(21_4_8_1_k);
  TEST_CLAUSE(21_4_8_1_l);
  TEST_CLAUSE(21_4_8_9_a);
}

TEST(FBString, testGetline) {
  string s1 =
      "\
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan \n\
elit ut urna consectetur in sagittis mi auctor. Nulla facilisi. In nec \n\
dolor leo, vitae imperdiet neque. Donec ut erat mauris, a faucibus \n\
elit. Integer consectetur gravida augue, sit amet mattis mauris auctor \n\
sed. Morbi congue libero eu nunc sodales adipiscing. In lectus nunc, \n\
vulputate a fringilla at, venenatis quis justo. Proin eu velit \n\
nibh. Maecenas vitae tellus eros. Pellentesque habitant morbi \n\
tristique senectus et netus et malesuada fames ac turpis \n\
egestas. Vivamus faucibus feugiat consequat. Donec fermentum neque sit \n\
amet ligula suscipit porta. Phasellus facilisis felis in purus luctus \n\
quis posuere leo tempor. Nam nunc purus, luctus a pharetra ut, \n\
placerat at dui. Donec imperdiet, diam quis convallis pulvinar, dui \n\
est commodo lorem, ut tincidunt diam nibh et nibh. Maecenas nec velit \n\
massa, ut accumsan magna. Donec imperdiet tempor nisi et \n\
laoreet. Phasellus lectus quam, ultricies ut tincidunt in, dignissim \n\
id eros. Mauris vulputate tortor nec neque pellentesque sagittis quis \n\
sed nisl. In diam lacus, lobortis ut posuere nec, ornare id quam.";

  vector<fbstring> v;
  boost::split(v, s1, boost::is_any_of("\n"));
  {
    istringstream input(s1);
    fbstring line;
    FOR_EACH (i, v) {
      EXPECT_TRUE(!getline(input, line).fail());
      EXPECT_EQ(line, *i);
    }
  }
}

TEST(FBString, testMoveCtor) {
  // Move constructor. Make sure we allocate a large string, so the
  // small string optimization doesn't kick in.
  auto size = random(100, 2000);
  fbstring s(size, 'a');
  fbstring test = std::move(s);
  EXPECT_TRUE(s.empty());
  EXPECT_EQ(size, test.size());
}

TEST(FBString, testMoveAssign) {
  // Move constructor. Make sure we allocate a large string, so the
  // small string optimization doesn't kick in.
  auto size = random(100, 2000);
  fbstring s(size, 'a');
  fbstring test;
  test = std::move(s);
  EXPECT_TRUE(s.empty());
  EXPECT_EQ(size, test.size());
}

TEST(FBString, testMoveOperatorPlusLhs) {
  // Make sure we allocate a large string, so the
  // small string optimization doesn't kick in.
  auto size1 = random(100, 2000);
  auto size2 = random(100, 2000);
  fbstring s1(size1, 'a');
  fbstring s2(size2, 'b');
  fbstring test;
  test = std::move(s1) + s2;
  EXPECT_TRUE(s1.empty());
  EXPECT_EQ(size1 + size2, test.size());
}

TEST(FBString, testMoveOperatorPlusRhs) {
  // Make sure we allocate a large string, so the
  // small string optimization doesn't kick in.
  auto size1 = random(100, 2000);
  auto size2 = random(100, 2000);
  fbstring s1(size1, 'a');
  fbstring s2(size2, 'b');
  fbstring test;
  test = s1 + std::move(s2);
  EXPECT_EQ(size1 + size2, test.size());
}

// The GNU C++ standard library throws an std::logic_error when an std::string
// is constructed with a null pointer. Verify that we mirror this behavior.
//
// N.B. We behave this way even if the C++ library being used is something
//      other than libstdc++. Someday if we deem it important to present
//      identical undefined behavior for other platforms, we can re-visit this.
TEST(FBString, testConstructionFromLiteralZero) {
  EXPECT_THROW(fbstring s(nullptr), std::logic_error);
}

TEST(FBString, testFixedBugs_D479397) {
  fbstring str(1337, 'f');
  fbstring cp = str;
  cp.clear();
  cp.c_str();
  EXPECT_EQ(str.front(), 'f');
}

TEST(FBString, testFixedBugs_D481173) {
  fbstring str(1337, 'f');
  for (int i = 0; i < 2; ++i) {
    fbstring cp = str;
    cp[1] = 'b';
    EXPECT_EQ(cp.c_str()[cp.size()], '\0');
    cp.push_back('?');
  }
}

TEST(FBString, testFixedBugs_D580267_push_back) {
  fbstring str(1337, 'f');
  fbstring cp = str;
  cp.push_back('f');
}

TEST(FBString, testFixedBugs_D580267_operator_add_assign) {
  fbstring str(1337, 'f');
  fbstring cp = str;
  cp += "bb";
}

TEST(FBString, testFixedBugs_D661622) {
  folly::basic_fbstring<wchar_t> s;
  EXPECT_EQ(0, s.size());
}

TEST(FBString, testFixedBugs_D785057) {
  fbstring str(1337, 'f');
  std::swap(str, str);
  EXPECT_EQ(1337, str.size());
}

TEST(FBString, testFixedBugs_D1012196_allocator_malloc) {
  fbstring str(128, 'f');
  str.clear(); // Empty medium string.
  fbstring copy(str); // Medium string of 0 capacity.
  copy.push_back('b');
  EXPECT_GE(copy.capacity(), 1);
}

TEST(FBString, testFixedBugs_D2813713) {
  fbstring s1("a");
  s1.reserve(8); // Trigger the optimized code path.
  auto test1 = '\0' + std::move(s1);
  EXPECT_EQ(2, test1.size());

  fbstring s2(1, '\0');
  s2.reserve(8);
  auto test2 = "a" + std::move(s2);
  EXPECT_EQ(2, test2.size());
}

TEST(FBString, testFixedBugs_D3698862) {
  EXPECT_EQ(fbstring().find(fbstring(), 4), fbstring::npos);
}

TEST(FBString, testFixedBugs_D4355440) {
  SKIP_IF(!usingJEMalloc());

  fbstring str(1337, 'f');
  str.reserve(3840);
  EXPECT_NE(str.capacity(), 3840);

  struct DummyRefCounted {
    std::atomic<size_t> refCount_;
  };
  EXPECT_EQ(
      str.capacity(),
      goodMallocSize(3840) - sizeof(DummyRefCounted) - sizeof(char));
}

TEST(FBString, findWithNpos) {
  fbstring fbstr("localhost:80");
  EXPECT_EQ(fbstring::npos, fbstr.find(":", fbstring::npos));
}

TEST(FBString, testHash) {
  fbstring a;
  fbstring b;
  a.push_back(0);
  a.push_back(1);
  b.push_back(0);
  b.push_back(2);
  std::hash<fbstring> hashfunc;
  EXPECT_NE(hashfunc(a), hashfunc(b));
}

#if FOLLY_HAVE_WCHAR_SUPPORT
TEST(FBString, testHashChar16) {
  using u16fbstring = folly::basic_fbstring<char16_t>;
  u16fbstring a;
  u16fbstring b;
  a.push_back(0);
  a.push_back(1);
  b.push_back(0);
  b.push_back(2);
  std::hash<u16fbstring> hashfunc;
  EXPECT_NE(hashfunc(a), hashfunc(b));
}
#endif

TEST(FBString, testFrontBack) {
  fbstring str("hello");
  EXPECT_EQ(str.front(), 'h');
  EXPECT_EQ(str.back(), 'o');
  str.front() = 'H';
  EXPECT_EQ(str.front(), 'H');
  str.back() = 'O';
  EXPECT_EQ(str.back(), 'O');
  EXPECT_EQ(str, "HellO");
}

TEST(FBString, noexcept) {
  EXPECT_TRUE(noexcept(fbstring()));
  fbstring x;
  EXPECT_FALSE(noexcept(fbstring(x)));
  EXPECT_TRUE(noexcept(fbstring(std::move(x))));
  fbstring y;
  EXPECT_FALSE(noexcept(y = x));
  EXPECT_TRUE(noexcept(y = std::move(x)));
}

TEST(FBString, iomanip) {
  stringstream ss;
  fbstring fbstr("Hello");

  ss << setw(6) << fbstr;
  EXPECT_EQ(ss.str(), " Hello");
  ss.str("");

  ss << left << setw(6) << fbstr;
  EXPECT_EQ(ss.str(), "Hello ");
  ss.str("");

  ss << right << setw(6) << fbstr;
  EXPECT_EQ(ss.str(), " Hello");
  ss.str("");

  ss << setw(4) << fbstr;
  EXPECT_EQ(ss.str(), "Hello");
  ss.str("");

  ss << setfill('^') << setw(6) << fbstr;
  EXPECT_EQ(ss.str(), "^Hello");
  ss.str("");
}

TEST(FBString, rvalueIterators) {
  // you cannot take &* of a move-iterator, so use that for testing
  fbstring s = "base";
  fbstring r = "hello";
  r.replace(
      r.begin(),
      r.end(),
      make_move_iterator(s.begin()),
      make_move_iterator(s.end()));
  EXPECT_EQ("base", r);

  // The following test is probably not required by the standard.
  // i.e. this could be in the realm of undefined behavior.
  fbstring b = "123abcXYZ";
  auto ait = b.begin() + 3;
  auto Xit = b.begin() + 6;
  b.replace(ait, b.end(), b.begin(), Xit);
  EXPECT_EQ("123123abc", b); // if things go wrong, you'd get "123123123"
}

TEST(FBString, moveTerminator) {
  // The source of a move must remain in a valid state
  fbstring s(100, 'x'); // too big to be in-situ
  fbstring k;
  k = std::move(s);

  EXPECT_EQ(0, s.size());
  EXPECT_EQ('\0', *s.c_str());
}

namespace {
/*
 * t8968589: Clang 3.7 refused to compile w/ certain constructors (specifically
 * those that were "explicit" and had a defaulted parameter, if they were used
 * in structs which were default-initialized).  Exercise these just to ensure
 * they compile.
 *
 * In diff D2632953 the old constructor:
 *   explicit basic_fbstring(const A& a = A()) noexcept;
 *
 * was split into these two, as a workaround:
 *   basic_fbstring() noexcept;
 *   explicit basic_fbstring(const A& a) noexcept;
 */

struct TestStructDefaultAllocator {
  folly::basic_fbstring<char> stringMember;
};

template <class A>
struct TestStructWithAllocator {
  folly::basic_fbstring<char, std::char_traits<char>, A> stringMember;
};

std::atomic<size_t> allocatorConstructedCount(0);
struct TestStructStringAllocator : std::allocator<char> {
  TestStructStringAllocator() {
    ++allocatorConstructedCount;
  }
};

} // namespace

TEST(FBStringCtorTest, DefaultInitStructDefaultAlloc) {
  TestStructDefaultAllocator t1{};
  EXPECT_TRUE(t1.stringMember.empty());
}

TEST(FBStringCtorTest, DefaultInitStructAlloc) {
  EXPECT_EQ(allocatorConstructedCount.load(), 0);
  TestStructWithAllocator<TestStructStringAllocator> t2;
  EXPECT_TRUE(t2.stringMember.empty());
  EXPECT_EQ(allocatorConstructedCount.load(), 1);
}

TEST(FBStringCtorTest, NullZeroConstruction) {
  char* p = nullptr;
  int n = 0;
  folly::fbstring f(p, n);
  EXPECT_EQ(f.size(), 0);
}

// Tests for the comparison operators. I use EXPECT_TRUE rather than EXPECT_LE
// because what's under test is the operator rather than the relation between
// the objects.

TEST(FBString, compareToStdString) {
  using folly::fbstring;
  using namespace std::string_literals;
  auto stdA = "a"s;
  auto stdB = "b"s;
  fbstring fbA("a");
  fbstring fbB("b");
  EXPECT_TRUE(stdA == fbA);
  EXPECT_TRUE(fbB == stdB);
  EXPECT_TRUE(stdA != fbB);
  EXPECT_TRUE(fbA != stdB);
  EXPECT_TRUE(stdA < fbB);
  EXPECT_TRUE(fbA < stdB);
  EXPECT_TRUE(stdB > fbA);
  EXPECT_TRUE(fbB > stdA);
  EXPECT_TRUE(stdA <= fbB);
  EXPECT_TRUE(fbA <= stdB);
  EXPECT_TRUE(stdA <= fbA);
  EXPECT_TRUE(fbA <= stdA);
  EXPECT_TRUE(stdB >= fbA);
  EXPECT_TRUE(fbB >= stdA);
  EXPECT_TRUE(stdB >= fbB);
  EXPECT_TRUE(fbB >= stdB);
}

TEST(U16FBString, compareToStdU16String) {
  using folly::basic_fbstring;
  using namespace std::string_literals;
  auto stdA = u"a"s;
  auto stdB = u"b"s;
  basic_fbstring<char16_t> fbA(u"a");
  basic_fbstring<char16_t> fbB(u"b");
  EXPECT_TRUE(stdA == fbA);
  EXPECT_TRUE(fbB == stdB);
  EXPECT_TRUE(stdA != fbB);
  EXPECT_TRUE(fbA != stdB);
  EXPECT_TRUE(stdA < fbB);
  EXPECT_TRUE(fbA < stdB);
  EXPECT_TRUE(stdB > fbA);
  EXPECT_TRUE(fbB > stdA);
  EXPECT_TRUE(stdA <= fbB);
  EXPECT_TRUE(fbA <= stdB);
  EXPECT_TRUE(stdA <= fbA);
  EXPECT_TRUE(fbA <= stdA);
  EXPECT_TRUE(stdB >= fbA);
  EXPECT_TRUE(fbB >= stdA);
  EXPECT_TRUE(stdB >= fbB);
  EXPECT_TRUE(fbB >= stdB);
}

TEST(U32FBString, compareToStdU32String) {
  using folly::basic_fbstring;
  using namespace std::string_literals;
  auto stdA = U"a"s;
  auto stdB = U"b"s;
  basic_fbstring<char32_t> fbA(U"a");
  basic_fbstring<char32_t> fbB(U"b");
  EXPECT_TRUE(stdA == fbA);
  EXPECT_TRUE(fbB == stdB);
  EXPECT_TRUE(stdA != fbB);
  EXPECT_TRUE(fbA != stdB);
  EXPECT_TRUE(stdA < fbB);
  EXPECT_TRUE(fbA < stdB);
  EXPECT_TRUE(stdB > fbA);
  EXPECT_TRUE(fbB > stdA);
  EXPECT_TRUE(stdA <= fbB);
  EXPECT_TRUE(fbA <= stdB);
  EXPECT_TRUE(stdA <= fbA);
  EXPECT_TRUE(fbA <= stdA);
  EXPECT_TRUE(stdB >= fbA);
  EXPECT_TRUE(fbB >= stdA);
  EXPECT_TRUE(stdB >= fbB);
  EXPECT_TRUE(fbB >= stdB);
}

TEST(WFBString, compareToStdWString) {
  using folly::basic_fbstring;
  using namespace std::string_literals;
  auto stdA = L"a"s;
  auto stdB = L"b"s;
  basic_fbstring<wchar_t> fbA(L"a");
  basic_fbstring<wchar_t> fbB(L"b");
  EXPECT_TRUE(stdA == fbA);
  EXPECT_TRUE(fbB == stdB);
  EXPECT_TRUE(stdA != fbB);
  EXPECT_TRUE(fbA != stdB);
  EXPECT_TRUE(stdA < fbB);
  EXPECT_TRUE(fbA < stdB);
  EXPECT_TRUE(stdB > fbA);
  EXPECT_TRUE(fbB > stdA);
  EXPECT_TRUE(stdA <= fbB);
  EXPECT_TRUE(fbA <= stdB);
  EXPECT_TRUE(stdA <= fbA);
  EXPECT_TRUE(fbA <= stdA);
  EXPECT_TRUE(stdB >= fbA);
  EXPECT_TRUE(fbB >= stdA);
  EXPECT_TRUE(stdB >= fbB);
  EXPECT_TRUE(fbB >= stdB);
}

// Same again, but with a more challenging input - a common prefix and different
// lengths.

TEST(FBString, compareToStdStringLong) {
  using folly::fbstring;
  using namespace std::string_literals;
  auto stdA = "1234567890a"s;
  auto stdB = "1234567890ab"s;
  fbstring fbA("1234567890a");
  fbstring fbB("1234567890ab");
  EXPECT_TRUE(stdA == fbA);
  EXPECT_TRUE(fbB == stdB);
  EXPECT_TRUE(stdA != fbB);
  EXPECT_TRUE(fbA != stdB);
  EXPECT_TRUE(stdA < fbB);
  EXPECT_TRUE(fbA < stdB);
  EXPECT_TRUE(stdB > fbA);
  EXPECT_TRUE(fbB > stdA);
  EXPECT_TRUE(stdA <= fbB);
  EXPECT_TRUE(fbA <= stdB);
  EXPECT_TRUE(stdA <= fbA);
  EXPECT_TRUE(fbA <= stdA);
  EXPECT_TRUE(stdB >= fbA);
  EXPECT_TRUE(fbB >= stdA);
  EXPECT_TRUE(stdB >= fbB);
  EXPECT_TRUE(fbB >= stdB);
}

TEST(U16FBString, compareToStdU16StringLong) {
  using folly::basic_fbstring;
  using namespace std::string_literals;
  auto stdA = u"1234567890a"s;
  auto stdB = u"1234567890ab"s;
  basic_fbstring<char16_t> fbA(u"1234567890a");
  basic_fbstring<char16_t> fbB(u"1234567890ab");
  EXPECT_TRUE(stdA == fbA);
  EXPECT_TRUE(fbB == stdB);
  EXPECT_TRUE(stdA != fbB);
  EXPECT_TRUE(fbA != stdB);
  EXPECT_TRUE(stdA < fbB);
  EXPECT_TRUE(fbA < stdB);
  EXPECT_TRUE(stdB > fbA);
  EXPECT_TRUE(fbB > stdA);
  EXPECT_TRUE(stdA <= fbB);
  EXPECT_TRUE(fbA <= stdB);
  EXPECT_TRUE(stdA <= fbA);
  EXPECT_TRUE(fbA <= stdA);
  EXPECT_TRUE(stdB >= fbA);
  EXPECT_TRUE(fbB >= stdA);
  EXPECT_TRUE(stdB >= fbB);
  EXPECT_TRUE(fbB >= stdB);
}

#if FOLLY_HAVE_WCHAR_SUPPORT
TEST(U32FBString, compareToStdU32StringLong) {
  using folly::basic_fbstring;
  using namespace std::string_literals;
  auto stdA = U"1234567890a"s;
  auto stdB = U"1234567890ab"s;
  basic_fbstring<char32_t> fbA(U"1234567890a");
  basic_fbstring<char32_t> fbB(U"1234567890ab");
  EXPECT_TRUE(stdA == fbA);
  EXPECT_TRUE(fbB == stdB);
  EXPECT_TRUE(stdA != fbB);
  EXPECT_TRUE(fbA != stdB);
  EXPECT_TRUE(stdA < fbB);
  EXPECT_TRUE(fbA < stdB);
  EXPECT_TRUE(stdB > fbA);
  EXPECT_TRUE(fbB > stdA);
  EXPECT_TRUE(stdA <= fbB);
  EXPECT_TRUE(fbA <= stdB);
  EXPECT_TRUE(stdA <= fbA);
  EXPECT_TRUE(fbA <= stdA);
  EXPECT_TRUE(stdB >= fbA);
  EXPECT_TRUE(fbB >= stdA);
  EXPECT_TRUE(stdB >= fbB);
  EXPECT_TRUE(fbB >= stdB);
}

TEST(WFBString, compareToStdWStringLong) {
  using folly::basic_fbstring;
  using namespace std::string_literals;
  auto stdA = L"1234567890a"s;
  auto stdB = L"1234567890ab"s;
  basic_fbstring<wchar_t> fbA(L"1234567890a");
  basic_fbstring<wchar_t> fbB(L"1234567890ab");
  EXPECT_TRUE(stdA == fbA);
  EXPECT_TRUE(fbB == stdB);
  EXPECT_TRUE(stdA != fbB);
  EXPECT_TRUE(fbA != stdB);
  EXPECT_TRUE(stdA < fbB);
  EXPECT_TRUE(fbA < stdB);
  EXPECT_TRUE(stdB > fbA);
  EXPECT_TRUE(fbB > stdA);
  EXPECT_TRUE(stdA <= fbB);
  EXPECT_TRUE(fbA <= stdB);
  EXPECT_TRUE(stdA <= fbA);
  EXPECT_TRUE(fbA <= stdA);
  EXPECT_TRUE(stdB >= fbA);
  EXPECT_TRUE(fbB >= stdA);
  EXPECT_TRUE(stdB >= fbB);
  EXPECT_TRUE(fbB >= stdB);
}
#endif

max_stars_repo_name: strager/folly

max_issues_repo_name: strager/folly

max_forks_repo_name: strager/folly


text:
#include <boost/assign.hpp>
#include <vector>
#include <deque>
#include <set>
#include <queue>

int main()
{
  std::vector<int> v;
  boost::assign::push_back(v)(1)(2)(3);

  std::deque<int> d;
  boost::assign::push_front(d)(1)(2)(3);

  std::set<int> s;
  boost::assign::insert(s)(1)(2)(3);

  std::queue<int> q;
  boost::assign::push(q)(1)(2)(3);
}

max_stars_repo_name: KwangjoJeong/Boost

max_issues_repo_name: KwangjoJeong/Boost

max_forks_repo_name: KwangjoJeong/Boost


text:
/*
 * Copyright Nick Thompson, 2020
 * Use, modification and distribution are subject to the
 * Boost Software License, Version 1.0. (See accompanying file
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 */

#include "math_unit_test.hpp"
#include <numeric>
#include <utility>
#include <vector>
#include <array>
#include <boost/random/uniform_real.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/math/interpolators/quintic_hermite.hpp>
#include <boost/math/special_functions/next.hpp>
#include <boost/circular_buffer.hpp>
#ifdef BOOST_HAS_FLOAT128
#include <boost/multiprecision/float128.hpp>
using boost::multiprecision::float128;
#endif

using boost::math::interpolators::quintic_hermite;
using boost::math::interpolators::cardinal_quintic_hermite;
using boost::math::interpolators::cardinal_quintic_hermite_aos;

template<typename Real>
void test_constant()
{
    std::vector<Real> x{0,1,2,3, 9, 22, 81};
    std::vector<Real> y(x.size());
    std::vector<Real> dydx(x.size(), 0);
    std::vector<Real> d2ydx2(x.size(), 0);
    for (auto & t : y)
    {
        t = 7;
    }

    auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2));
    for (Real t = 0; t <= 81; t += 0.25)
    {
        CHECK_ULP_CLOSE(Real(7), qh(t), 24);
        CHECK_ULP_CLOSE(Real(0), qh.prime(t), 24);
        CHECK_ULP_CLOSE(Real(0), qh.double_prime(t), 24);
    }
}

template<typename Real>
void test_linear()
{
    std::vector<Real> x{0,1,2,3, 4,5,6,7,8,9};
    std::vector<Real> y = x;
    std::vector<Real> dydx(x.size(), 1);
    std::vector<Real> d2ydx2(x.size(), 0);

    auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2));

    for (Real t = 0; t <= 9; t += 0.25)
    {
        CHECK_ULP_CLOSE(Real(t), qh(t), 2);
        CHECK_ULP_CLOSE(Real(1), qh.prime(t), 2);
        CHECK_ULP_CLOSE(Real(0), qh.double_prime(t), 2);
    }

    boost::random::mt19937 rng;
    boost::random::uniform_real_distribution<Real> dis(0.5,1);
    x.resize(512);
    x[0] = dis(rng);
    Real xmin = x[0];
    for (size_t i = 1; i < x.size(); ++i)
    {
        x[i] = x[i-1] + dis(rng);
    }
    Real xmax = x.back();

    y = x;
    dydx.resize(x.size(), 1);
    d2ydx2.resize(x.size(), 0);

    qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2));

    for (Real t = xmin; t <= xmax; t += 0.125)
    {
        CHECK_ULP_CLOSE(t, qh(t), 2);
        CHECK_ULP_CLOSE(Real(1), qh.prime(t), 100);
        CHECK_MOLLIFIED_CLOSE(Real(0), qh.double_prime(t), 200*std::numeric_limits<Real>::epsilon());
    }
}

template<typename Real>
void test_quadratic()
{

    std::vector<Real> x{0,1,2,3, 4,5,6,7,8,9};
    std::vector<Real> y(x.size());
    for (size_t i = 0; i < y.size(); ++i)
    {
        y[i] = x[i]*x[i]/2;
    }

    std::vector<Real> dydx(x.size());
    for (size_t i = 0; i < y.size(); ++i) {
        dydx[i] = x[i];
    }

    std::vector<Real> d2ydx2(x.size(), 1);

    auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2));

    for (Real t = 0; t <= 9; t += 0.0078125)
    {
        CHECK_ULP_CLOSE(Real(t*t)/2, qh(t), 2);
        CHECK_ULP_CLOSE(t, qh.prime(t), 12);
        CHECK_ULP_CLOSE(Real(1), qh.double_prime(t), 32);
    }

    boost::random::mt19937 rng;
    boost::random::uniform_real_distribution<Real> dis(0.5,1);
    x.resize(8);
    x[0] = dis(rng);
    Real xmin = x[0];
    for (size_t i = 1; i < x.size(); ++i)
    {
        x[i] = x[i-1] + dis(rng);
    }
    Real xmax = x.back();

    y.resize(x.size());
    for (size_t i = 0; i < y.size(); ++i)
    {
        y[i] = x[i]*x[i]/2;
    }

    dydx.resize(x.size());
    for (size_t i = 0; i < y.size(); ++i)
    {
        dydx[i] = x[i];
    }

    d2ydx2.resize(x.size(), 1);

    qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2));

    for (Real t = xmin; t <= xmax; t += 0.125)
    {
        CHECK_ULP_CLOSE(Real(t*t)/2, qh(t), 4);
        CHECK_ULP_CLOSE(t, qh.prime(t), 53);
        CHECK_ULP_CLOSE(Real(1), qh.double_prime(t), 700);
    }
}

template<typename Real>
void test_cubic()
{

    std::vector<Real> x{0,1,2,3, 4,5,6,7,8,9};
    std::vector<Real> y(x.size());
    for (size_t i = 0; i < y.size(); ++i)
    {
        y[i] = x[i]*x[i]*x[i];
    }

    std::vector<Real> dydx(x.size());
    for (size_t i = 0; i < y.size(); ++i) {
        dydx[i] = 3*x[i]*x[i];
    }

    std::vector<Real> d2ydx2(x.size());
    for (size_t i = 0; i < y.size(); ++i)
    {
        d2ydx2[i] = 6*x[i];
    }

    auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2));

    for (Real t = 0; t <= 9; t += 0.0078125)
    {
        CHECK_ULP_CLOSE(t*t*t, qh(t), 10);
        CHECK_ULP_CLOSE(3*t*t, qh.prime(t), 15);
        CHECK_ULP_CLOSE(6*t, qh.double_prime(t), 20);
    }
}

template<typename Real>
void test_quartic()
{

    std::vector<Real> x{0,1,2,3, 4,5,6,7,8,9, 10, 11};
    std::vector<Real> y(x.size());
    for (size_t i = 0; i < y.size(); ++i)
    {
        y[i] = x[i]*x[i]*x[i]*x[i];
    }

    std::vector<Real> dydx(x.size());
    for (size_t i = 0; i < y.size(); ++i)
    {
        dydx[i] = 4*x[i]*x[i]*x[i];
    }

    std::vector<Real> d2ydx2(x.size());
    for (size_t i = 0; i < y.size(); ++i)
    {
        d2ydx2[i] = 12*x[i]*x[i];
    }

    auto qh = quintic_hermite(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2));

    for (Real t = 1; t <= 11; t += 0.0078125)
    {
        CHECK_ULP_CLOSE(t*t*t*t, qh(t), 100);
        CHECK_ULP_CLOSE(4*t*t*t, qh.prime(t), 100);
        CHECK_ULP_CLOSE(12*t*t, qh.double_prime(t), 100);
    }
}

template<typename Real>
void test_interpolation_condition()
{
    for (size_t n = 4; n < 50; ++n) {
        std::vector<Real> x(n);
        std::vector<Real> y(n);
        std::vector<Real> dydx(n);
        std::vector<Real> d2ydx2(n);
        boost::random::mt19937 rd;
        boost::random::uniform_real_distribution<Real> dis(0,1);
        Real x0 = dis(rd);
        x[0] = x0;
        y[0] = dis(rd);
        for (size_t i = 1; i < n; ++i) {
            x[i] = x[i-1] + dis(rd);
            y[i] = dis(rd);
            dydx[i] = dis(rd);
            d2ydx2[i] = dis(rd);
        }

        auto x_copy = x;
        auto y_copy = y;
        auto dydx_copy = dydx;
        auto d2ydx2_copy = d2ydx2;
        auto s = quintic_hermite(std::move(x_copy), std::move(y_copy), std::move(dydx_copy), std::move(d2ydx2_copy));
        //std::cout << "s = " << s << "\n";
        for (size_t i = 0; i < x.size(); ++i) {
            CHECK_ULP_CLOSE(y[i], s(x[i]), 2);
            CHECK_ULP_CLOSE(dydx[i], s.prime(x[i]), 2);
            CHECK_ULP_CLOSE(d2ydx2[i], s.double_prime(x[i]), 2);
        }
    }
}

template<typename Real>
void test_cardinal_constant()
{

    std::vector<Real> y(25);
    std::vector<Real> dydx(y.size(), 0);
    std::vector<Real> d2ydx2(y.size(), 0);
    for (auto & t : y) {
        t = 7;
    }
    Real x0 = 4;
    Real dx = Real(1)/Real(8);

    auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx);

    for (Real t = x0; t <= x0 + 24*dx; t += 0.25)
    {
        CHECK_ULP_CLOSE(Real(7), qh(t), 24);
        CHECK_ULP_CLOSE(Real(0), qh.prime(t), 24);
        CHECK_ULP_CLOSE(Real(0), qh.double_prime(t), 24);
    }

    std::vector<std::array<Real, 3>> data(25);
    for (size_t i = 0; i < data.size(); ++i)
    {
        data[i][0] = 7;
        data[i][1] = 0;
        data[i][2] = 0;
    }

    auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx);
    for (Real t = x0; t <= x0 + 24*dx; t += 0.25)
    {
        CHECK_ULP_CLOSE(Real(7), qh_aos(t), 24);
        CHECK_ULP_CLOSE(Real(0), qh_aos.prime(t), 24);
        CHECK_ULP_CLOSE(Real(0), qh_aos.double_prime(t), 24);
    }

    // Now check the boundaries:
    auto [tlo, thi] = qh.domain();
    int samples = 5000;
    int i = 0;
    while (i++ < samples)
    {
        CHECK_ULP_CLOSE(Real(7), qh(tlo), 2);
        CHECK_ULP_CLOSE(Real(7), qh(thi), 2);
        CHECK_ULP_CLOSE(Real(7), qh_aos(tlo), 2);
        CHECK_ULP_CLOSE(Real(7), qh_aos(thi), 2);
        CHECK_ULP_CLOSE(Real(0), qh.prime(tlo), 2);
        CHECK_ULP_CLOSE(Real(0), qh.prime(thi), 2);
        CHECK_ULP_CLOSE(Real(0), qh_aos.prime(tlo), 2);
        CHECK_ULP_CLOSE(Real(0), qh_aos.prime(thi), 2);

        tlo = boost::math::nextafter(tlo, std::numeric_limits<Real>::max());
        thi = boost::math::nextafter(thi, std::numeric_limits<Real>::lowest());
    }
}

template<typename Real>
void test_cardinal_linear()
{
    std::vector<Real> y{0,1,2,3,4,5,6,7,8,9};
    Real x0 = 0;
    Real dx = 1;
    std::vector<Real> dydx(y.size(), 1);
    std::vector<Real> d2ydx2(y.size(), 0);

    auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx);

    for (Real t = 0; t <= 9; t += 0.25) {
        CHECK_ULP_CLOSE(Real(t), qh(t), 2);
        CHECK_ULP_CLOSE(Real(1), qh.prime(t), 2);
        CHECK_ULP_CLOSE(Real(0), qh.double_prime(t), 2);
    }

    std::vector<std::array<Real, 3>> data(10);
    for (size_t i = 0; i < data.size(); ++i) {
        data[i][0] = i;
        data[i][1] = 1;
        data[i][2] = 0;
    }

    auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx);

    for (Real t = 0; t <= 9; t += 0.25) {
        CHECK_ULP_CLOSE(Real(t), qh_aos(t), 2);
        CHECK_ULP_CLOSE(Real(1), qh_aos.prime(t), 2);
        CHECK_ULP_CLOSE(Real(0), qh_aos.double_prime(t), 2);
    }

    // Now check the boundaries:
    auto [tlo, thi] = qh.domain();
    int samples = 5000;
    int i = 0;
    while (i++ < samples)
    {
        CHECK_ULP_CLOSE(Real(tlo), qh(tlo), 2);
        CHECK_ULP_CLOSE(Real(thi), qh(thi), 2);
        CHECK_ULP_CLOSE(Real(tlo), qh_aos(tlo), 2);
        CHECK_ULP_CLOSE(Real(thi), qh_aos(thi), 2);
        CHECK_ULP_CLOSE(Real(1), qh.prime(tlo), 2);
        CHECK_ULP_CLOSE(Real(1), qh.prime(thi), 128);
        CHECK_ULP_CLOSE(Real(1), qh_aos.prime(tlo), 2);
        CHECK_ULP_CLOSE(Real(1), qh_aos.prime(thi), 128);

        tlo = boost::math::nextafter(tlo, std::numeric_limits<Real>::max());
        thi = boost::math::nextafter(thi, std::numeric_limits<Real>::lowest());
    }
}

template<typename Real>
void test_cardinal_quadratic()
{
    Real x0 = 0;
    Real dx = 1;
    std::vector<Real> y(10);
    for (size_t i = 0; i < y.size(); ++i)
    {
        y[i] = i*i/Real(2);
    }

    std::vector<Real> dydx(y.size());
    for (size_t i = 0; i < y.size(); ++i) {
        dydx[i] = i;
    }

    std::vector<Real> d2ydx2(y.size(), 1);

    auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx);

    for (Real t = 0; t <= 9; t += 0.0078125) {
        Real computed = qh(t);
        CHECK_ULP_CLOSE(Real(t*t)/2, computed, 2);
        CHECK_ULP_CLOSE(t, qh.prime(t), 15);
        CHECK_ULP_CLOSE(Real(1), qh.double_prime(t), 32);
    }

    std::vector<std::array<Real, 3>> data(10);
    for (size_t i = 0; i < data.size(); ++i) {
        data[i][0] = i*i/Real(2);
        data[i][1] = i;
        data[i][2] = 1;
    }
    auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx);

    for (Real t = 0; t <= 9; t += 0.0078125)
    {
        Real computed = qh_aos(t);
        CHECK_ULP_CLOSE(Real(t*t)/2, computed, 2);
        CHECK_ULP_CLOSE(t, qh_aos.prime(t), 12);
        CHECK_ULP_CLOSE(Real(1), qh_aos.double_prime(t), 64);
    }

        // Now check the boundaries:
    auto [tlo, thi] = qh.domain();
    int samples = 5000;
    int i = 0;
    while (i++ < samples)
    {
        CHECK_ULP_CLOSE(tlo*tlo/2, qh(tlo), 16);
        CHECK_ULP_CLOSE(thi*thi/2, qh(thi), 16);
        CHECK_ULP_CLOSE(tlo*tlo/2, qh_aos(tlo), 16);
        CHECK_ULP_CLOSE(thi*thi/2, qh_aos(thi), 16);
        CHECK_ULP_CLOSE(tlo, qh.prime(tlo), 16);
        CHECK_ULP_CLOSE(thi, qh.prime(thi), 64);
        CHECK_ULP_CLOSE(tlo, qh_aos.prime(tlo), 16);
        CHECK_ULP_CLOSE(thi, qh_aos.prime(thi), 64);

        tlo = boost::math::nextafter(tlo, std::numeric_limits<Real>::max());
        thi = boost::math::nextafter(thi, std::numeric_limits<Real>::lowest());
    }
}

template<typename Real>
void test_cardinal_cubic()
{
    Real x0 = 0;
    Real dx = 1;
    std::vector<Real> y(10);
    for (size_t i = 0; i < y.size(); ++i)
    {
        y[i] = i*i*i;
    }

    std::vector<Real> dydx(y.size());
    for (size_t i = 0; i < y.size(); ++i) {
        dydx[i] = 3*i*i;
    }

    std::vector<Real> d2ydx2(y.size());
    for (size_t i = 0; i < y.size(); ++i) {
        d2ydx2[i] = 6*i;
    }

    auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx);

    for (Real t = 0; t <= 9; t += 0.0078125)
    {
        Real computed = qh(t);
        CHECK_ULP_CLOSE(t*t*t, computed, 10);
        CHECK_ULP_CLOSE(3*t*t, qh.prime(t), 15);
        CHECK_ULP_CLOSE(6*t, qh.double_prime(t), 39);
    }

    std::vector<std::array<Real, 3>> data(10);
    for (size_t i = 0; i < data.size(); ++i) {
        data[i][0] = i*i*i;
        data[i][1] = 3*i*i;
        data[i][2] = 6*i;
    }

    auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx);
    for (Real t = 0; t <= 9; t += 0.0078125)
    {
        Real computed = qh_aos(t);
        CHECK_ULP_CLOSE(t*t*t, computed, 10);
        CHECK_ULP_CLOSE(3*t*t, qh_aos.prime(t), 15);
        CHECK_ULP_CLOSE(6*t, qh_aos.double_prime(t), 30);
    }
}

template<typename Real>
void test_cardinal_quartic()
{
    Real x0 = 0;
    Real dx = 1;
    std::vector<Real> y(7);
    for (size_t i = 0; i < y.size(); ++i)
    {
        y[i] = i*i*i*i;
    }

    std::vector<Real> dydx(y.size());
    for (size_t i = 0; i < y.size(); ++i) {
        dydx[i] = 4*i*i*i;
    }

    std::vector<Real> d2ydx2(y.size());
    for (size_t i = 0; i < y.size(); ++i) {
        d2ydx2[i] = 12*i*i;
    }

    auto qh = cardinal_quintic_hermite(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx);

    for (Real t = 0; t <= 6; t += 0.0078125)
    {
        CHECK_ULP_CLOSE(Real(t*t*t*t), qh(t), 250);
        CHECK_ULP_CLOSE(4*t*t*t, qh.prime(t), 250);
        CHECK_ULP_CLOSE(12*t*t, qh.double_prime(t), 250);
    }

    std::vector<std::array<Real, 3>> data(7);
    for (size_t i = 0; i < data.size(); ++i) {
        data[i][0] = i*i*i*i;
        data[i][1] = 4*i*i*i;
        data[i][2] = 12*i*i;
    }

    auto qh_aos = cardinal_quintic_hermite_aos(std::move(data), x0, dx);
    for (Real t = 0; t <= 6; t += 0.0078125)
    {
        Real computed = qh_aos(t);
        CHECK_ULP_CLOSE(t*t*t*t, computed, 10);
        CHECK_ULP_CLOSE(4*t*t*t, qh_aos.prime(t), 64);
        CHECK_ULP_CLOSE(12*t*t, qh_aos.double_prime(t), 128);
    }
}

int main()
{
    test_constant<float>();
    test_linear<float>();
    test_quadratic<float>();
    test_cubic<float>();
    test_quartic<float>();
    test_interpolation_condition<float>();

    test_cardinal_constant<float>();
    test_cardinal_linear<float>();
    test_cardinal_quadratic<float>();
    test_cardinal_cubic<float>();
    test_cardinal_quartic<float>();

    test_constant<double>();
    test_linear<double>();
    test_quadratic<double>();
    test_cubic<double>();
    test_quartic<double>();
    test_interpolation_condition<double>();

    test_cardinal_constant<double>();
    test_cardinal_linear<double>();
    test_cardinal_quadratic<double>();
    test_cardinal_cubic<double>();
    test_cardinal_quartic<double>();

    test_constant<long double>();
    test_linear<long double>();
    test_quadratic<long double>();
    test_cubic<long double>();
    test_quartic<long double>();
    test_interpolation_condition<long double>();

    test_cardinal_constant<long double>();
    test_cardinal_linear<long double>();
    test_cardinal_quadratic<long double>();
    test_cardinal_cubic<long double>();
    test_cardinal_quartic<long double>();

#ifdef BOOST_HAS_FLOAT128
    test_constant<float128>();
    //test_linear<float128>();
    test_quadratic<float128>();
    test_cubic<float128>();
    test_quartic<float128>();
    test_interpolation_condition<float128>();
    test_cardinal_constant<float128>();
    test_cardinal_linear<float128>();
    test_cardinal_quadratic<float128>();
    test_cardinal_cubic<float128>();
    test_cardinal_quartic<float128>();
#endif

    return boost::math::test::report_errors();
}

max_issues_repo_name: qingkouwei/mediaones

max_forks_repo_name: qingkouwei/mediaones


text:
/************************************************************************
 Copyright 2018 andrewpqc@mails.ccnu.edu.cn
 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.
 ************************************************************************/

#ifndef _BASE_SERVER_HPP_
#define _BASE_SERVER_HPP_

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

#include <iostream>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>
#include <typeinfo>
#include <functional>

#include "group.hpp"
#include "logo.hpp"
#include "utils.hpp"
#include "logger.hpp"
#include "request.hpp"
#include "response.hpp"
#include "context.hpp"
#include "static.hpp"
#include "default_error_handler.hpp"

namespace vogro {
    /*url , method, handlers*/
    using  RegistrationCenter =  std::map<std::string, std::unordered_map<std::string,
                                           std::vector<std::function<void(vogro::Context &)>>>>;

    template<typename socket_type>
    class ServerBase {
    protected:
        boost::asio::io_service io_svc;
        boost::asio::ip::tcp::endpoint endpoint;
        boost::asio::ip::tcp::acceptor acceptor;

        unsigned short port_;

        size_t thread_num;
        std::vector<std::thread> threads;
        std::vector<RegistrationCenter::iterator> all_resources;

        RegistrationCenter user_resource;
        RegistrationCenter vogro_resource;

        std::function<void(vogro::Request &, vogro::Response &)
                > default_error_handler = DefaultErrorHandler;

        std::unordered_map<unsigned short,
            std::function<void(vogro::Request &, vogro::Response &)>
                          > error_handlers;

        std::vector<std::function<void(vogro::Context &)>> globalMiddlewares;

        Logger<TerminalPolicy> &logger = Logger<TerminalPolicy>::getLoggerInstance("vogro.log");

        virtual void accept() {}

    private:
        void addHandler(const std::string &path, const std::string &method) {
            logger.LOG_INFO(path, method, "handlers register ok");
        }

        template<typename First, typename... Rest>
        void addHandler(const std::string &path, const std::string &method, const First &parm1,
                        const Rest &... parm) {
            this->user_resource[path][method].push_back(parm1);
            addHandler(path, method, parm...);
        }

    public:
        ServerBase(unsigned short port, size_t num_threads)
                : endpoint(boost::asio::ip::tcp::v4(), port),
                  acceptor(io_svc, endpoint),
                  thread_num(num_threads),
                  port_(port) {}

        void run() {
            for (auto it = user_resource.begin(); it != user_resource.end(); it++)
                all_resources.push_back(it);

            for (auto it = vogro_resource.begin(); it != vogro_resource.end(); it++)
                all_resources.push_back(it);

            printLogo(port_, __VOGRO_VERSION__);

            accept();

            // n-1 thread pool
            for (size_t c = 1; c < thread_num; c++) {
                threads.emplace_back([this]() { io_svc.run(); });
            }

            // main thread
            io_svc.run();

            for (auto &t : threads)
                t.join();
        }

    protected:

        void process_request_and_respond(std::shared_ptr<socket_type> socket) const {

            auto read_buffer = std::make_shared<boost::asio::streambuf>();
            boost::asio::async_read_until(*socket, *read_buffer, "\r\n\r\n",
              [this, socket, read_buffer](const boost::system::error_code &ec,
                                          size_t bytes_transferred) {
                  if (!ec) {
                      size_t total = read_buffer->size();

                      std::istream stream(read_buffer.get());

                      auto request = std::make_shared<vogro::Request>();
                      *request = parse_request(stream);

                      request->setRemoteIP(
                              socket->lowest_layer().remote_endpoint().address().to_string());
                      request->setRemotePort(
                              socket->lowest_layer().remote_endpoint().port());

                      size_t num_additional_bytes = total - bytes_transferred;
                      std::string content_length_header = request->getHeader(
                              "Content-Length");
                      if (!content_length_header.empty()) {
                          auto content_length = std::stoull(content_length_header);
                          auto remain_body_length = content_length - num_additional_bytes;
                          boost::asio::async_read(*socket, *read_buffer,
                                  boost::asio::transfer_exactly(remain_body_length),
                                  [this, socket, read_buffer, request](
                                          const boost::system::error_code &ec,
                                          size_t bytes_transferred) {
                                      if (!ec) {
                                          request->setBody(std::shared_ptr<std::istream>(
                                                          new std::istream(read_buffer.get())));
                                          respond(socket, request);
                                      }
                          });
                      } else {
                          respond(socket, request);
                      }
                  }
            });
        }

    private:
        vogro::Request parse_request(std::istream &stream) const {
            vogro::Request req;

            // parse request line
            std::string line;
            getline(stream, line);
            line.pop_back(); //去掉换行符
            auto threesome = parse_request_line(line);
            req.setMethod(threesome.first);
            req.setVersion(threesome.second.second);

            std::string url = threesome.second.first;

            std::size_t pos = url.find_first_of('?');
            if (pos == std::string::npos) {
                req.setPath(url);
            } else {
                std::string path = url.substr(0, pos);
                req.setPath(path);

                std::string query_string = url.substr(pos + 1);
                req.setQueryParam(query_string);
            }

            // parse request headers
            while (true) {
                getline(stream, line);
                line.pop_back();

                if (line.empty()) break;

                auto headerpair = parse_header(line);
                req.addHeader(headerpair.first, headerpair.second);
            }

            return req;
        }

        void respond(std::shared_ptr<socket_type> socket,
                     std::shared_ptr<vogro::Request> request) const {
            auto write_buffer = std::make_shared<boost::asio::streambuf>();
            std::ostream responseStream(write_buffer.get());

            auto response = std::make_shared<vogro::Response>();

            bool matchedOne = false;
            for (auto res_it : all_resources) {
                std::map<std::string, std::string> tempPathParamStoreMap;
                auto matchResult = urlMatch(request->getPath(), res_it->first, tempPathParamStoreMap);
                if ((!matchResult.first) && (matchResult.second)) {
                    ServeStatic(*response, *request, responseStream, write_buffer, socket);
                    matchedOne = true;
                    // break;
                    return;
                } else if ((matchResult.first) && (!matchResult.second)) {
                    if (res_it->second.count(request->getMethod()) > 0) {
                        request->setPathParam(tempPathParamStoreMap);

                        Context ctx(request, response, globalMiddlewares,
                                    res_it->second[request->getMethod()]);

                        if (globalMiddlewares.begin() != globalMiddlewares.end()) {
                            (*(globalMiddlewares.begin()))(ctx);
                        } else {
                            if (res_it->second[request->getMethod()].begin() !=
                                res_it->second[request->getMethod()].end()) {
                                (*(res_it->second[request->getMethod()].begin()))(ctx);
                            }
                        }

                        matchedOne = true;
                        break;
                    } else {
                        response->setCode(CodeMethodNotAllowed_405, "Method Not Allowed");
                        auto got = error_handlers.find(CodeMethodNotAllowed_405);
                        if (got == error_handlers.end())
                            default_error_handler(*request, *response);
                        else
                            got->second(*request, *response);
                        matchedOne = true;
                        break;
                    }
                }
            }

            if (!matchedOne) {
                response->setCode(CodeNotFound_404, "Not Found");
                auto got = error_handlers.find(CodeNotFound_404);
                if (got == error_handlers.end())
                    default_error_handler(*request, *response);
                else
                    got->second(*request, *response);
            }

            responseStream << response->makeResponseMsg();
            int respCode = response->getCode();
            boost::asio::async_write(
                    *socket, *write_buffer,
                    [this, socket, request, write_buffer, respCode](
                            const boost::system::error_code &ec, size_t bytes_transferred) {

                        logger.LOG_DEBUG(request->getRemoteIP(), request->getMethod(),
                                         request->getPath(), respCode);

                        if (!ec && std::stof(request->getVersion()) > 1.05)
                            process_request_and_respond(socket);
                    });
            return;
        }

    public:
        void addRoute(const std::string &userPath, const std::string &method,
                      const std::function<void(vogro::Context &)> handler) {
            this->user_resource[userPath][method].push_back(handler);
        }

        template<typename... Args>
        void Get(const std::string &userPath, const Args &... args) {
            this->addHandler(userPath, "GET", args...);
        }

        template<typename... Args>
        void Post(const std::string &userPath, const Args &... args) {
            this->addHandler(userPath, "POST", args...);
        }

        template<typename... Args>
        void Put(const std::string &userPath, const Args &... args) {
            this->addHandler(userPath, "PUT", args...);
        }

        template<typename... Args>
        void Delete(const std::string &userPath, const Args &... args) {
            this->addHandler(userPath, "PUT", args...);
        }

        std::shared_ptr<vogro::Group> makeGroup(std::string &&prefix,
                  const std::function<void(vogro::Context &)> &handler) {
            if (prefix.back() == '/')
                prefix.pop_back();
            return std::make_shared<vogro::Group>(prefix, user_resource, handler);
        }

        std::shared_ptr<vogro::Group> makeGroup(std::string &&prefix) {
            if (prefix.back() == '/')
                prefix.pop_back();
            return std::make_shared<vogro::Group>(prefix, user_resource);
        };

        void onError(
                unsigned short code,
                std::function<void(vogro::Request &, vogro::Response &)> handler) {
            this->error_handlers[code] = handler;
        }

        void Use(std::function<void(vogro::Context &)> middleware) {
            this->globalMiddlewares.push_back(middleware);
        }
    }; // class ServerBase
} // namespace vogro

#endif

max_stars_repo_name: vogro-x/vogro

max_issues_repo_name: vogro-x/vogro

max_forks_repo_name: vogro-x/vogro


text:
#pragma once

#include <polyfem/ElementAssemblyValues.hpp>
#include <polyfem/ElementBases.hpp>
#include <polyfem/AutodiffTypes.hpp>
#include <polyfem/Types.hpp>

#include <Eigen/Dense>
#include <vector>
#include <array>
#include <functional>

namespace polyfem
{
	constexpr int SMALL_N = POLYFEM_SMALL_N;
	constexpr int BIG_N = POLYFEM_BIG_N;

	Eigen::VectorXd gradient_from_energy(const int size, const int n_bases, const ElementAssemblyValues &vals, const Eigen::MatrixXd &displacement, const QuadratureVector &da,
		const std::function<DScalar1<double, Eigen::Matrix<double, 6, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun6,
		const std::function<DScalar1<double, Eigen::Matrix<double, 8, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun8,
		const std::function<DScalar1<double, Eigen::Matrix<double, 12, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun12,
		const std::function<DScalar1<double, Eigen::Matrix<double, 18, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun18,
		const std::function<DScalar1<double, Eigen::Matrix<double, 24, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun24,
		const std::function<DScalar1<double, Eigen::Matrix<double, 30, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun30,
		const std::function<DScalar1<double, Eigen::Matrix<double, 60, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun60,
		const std::function<DScalar1<double, Eigen::Matrix<double, 81, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun81,
		const std::function<DScalar1<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, SMALL_N, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &funN,
		const std::function<DScalar1<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 1000, 1>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &funBigN,
		const std::function<DScalar1<double, Eigen::VectorXd>				(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &funn
		);

	Eigen::MatrixXd hessian_from_energy(const int size, const int n_bases, const ElementAssemblyValues &vals, const Eigen::MatrixXd &displacement, const QuadratureVector &da,
		const std::function<DScalar2<double, Eigen::Matrix<double, 6, 1>, Eigen::Matrix<double, 6, 6>>		(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun6,
		const std::function<DScalar2<double, Eigen::Matrix<double, 8, 1>, Eigen::Matrix<double, 8, 8>>		(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun8,
		const std::function<DScalar2<double, Eigen::Matrix<double, 12, 1>, Eigen::Matrix<double, 12, 12>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun12,
		const std::function<DScalar2<double, Eigen::Matrix<double, 18, 1>, Eigen::Matrix<double, 18, 18>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun18,
		const std::function<DScalar2<double, Eigen::Matrix<double, 24, 1>, Eigen::Matrix<double, 24, 24>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun24,
		const std::function<DScalar2<double, Eigen::Matrix<double, 30, 1>, Eigen::Matrix<double, 30, 30>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun30,
		const std::function<DScalar2<double, Eigen::Matrix<double, 60, 1>, Eigen::Matrix<double, 60, 60>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun60,
		const std::function<DScalar2<double, Eigen::Matrix<double, 81, 1>, Eigen::Matrix<double, 81, 81>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &fun81,
		const std::function<DScalar2<double, Eigen::Matrix<double, Eigen::Dynamic, 1, 0, SMALL_N, 1>, Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, SMALL_N, SMALL_N>>	(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &funN,
		const std::function<DScalar2<double, Eigen::VectorXd, Eigen::MatrixXd>								(const ElementAssemblyValues &, const Eigen::MatrixXd &, const QuadratureVector &)> &funn
		);

	double von_mises_stress_for_stress_tensor(const Eigen::MatrixXd &stress);
	void compute_diplacement_grad(const int size, const ElementBases &bs, const ElementAssemblyValues &vals, const Eigen::MatrixXd &local_pts, const int p, const Eigen::MatrixXd &displacement, Eigen::MatrixXd &displacement_grad);

	double convert_to_lambda(const bool is_volume, const double E, const double nu);
	double convert_to_mu(const double E, const double nu);

	class ElasticityTensor
	{
	public:
		void resize(const int size);

		double operator()(int i, int j) const;
		double &operator()(int i, int j);

		void set_from_entries(const std::vector<double> &entries);
		void set_from_lambda_mu(const double lambda, const double mu);
		void set_from_young_poisson(const double young, const double poisson);

		void set_orthotropic(
		double   Ex, double   Ey, double   Ez,
		double nuYX, double nuZX, double nuZY,
		double muYZ, double muZX, double muXY);
		void set_orthotropic(double Ex, double Ey, double nuYX, double muXY);

		template<int DIM>
		double compute_stress(const std::array<double, DIM> &strain, const int j) const;

	private:
		Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, 0, 6, 6> stifness_tensor_;
		int size_;
	};
}

max_stars_repo_name: ldXiao/polyfem

max_issues_repo_name: ldXiao/polyfem

max_forks_repo_name: ldXiao/polyfem


text:
/*
 * Copyright 2020 Adobe. All rights reserved.
 * This file is licensed to you 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 REPRESENTATIONS
 * OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
#include <lagrange/testing/common.h>

#include <lagrange/utils/geometry2d.h>
#include <Eigen/Core>

TEST_CASE("utils-geometry2d")
{
    using namespace lagrange;
    using Vec2 = Eigen::Vector2d;

    REQUIRE(sqr_minimum_distance(Vec2(0, 0), Vec2(0, 1), Vec2(0, 0)) == 0.0);
    REQUIRE(sqr_minimum_distance(Vec2(0, 0), Vec2(0, 1), Vec2(0, 1)) == 0.0);
    REQUIRE(sqr_minimum_distance(Vec2(0, 0), Vec2(0, 1), Vec2(0, .5)) == 0.0);

    REQUIRE(sqr_minimum_distance(Vec2(0, 0), Vec2(0, 1), Vec2(1, 0)) == (1 * 1));
    REQUIRE(sqr_minimum_distance(Vec2(0, 0), Vec2(0, 1), Vec2(1, .2)) == (1 * 1));

    REQUIRE(sqr_minimum_distance(Vec2(0, 0), Vec2(0, 1), Vec2(0, -1)) == (1 * 1));
    REQUIRE(sqr_minimum_distance(Vec2(0, 0), Vec2(0, 1), Vec2(0, 2)) == (1 * 1));
    REQUIRE(sqr_minimum_distance(Vec2(0, 0), Vec2(0, 1), Vec2(0, 3)) == (2 * 2));

    REQUIRE(sqr_minimum_distance(Vec2(0, 0), Vec2(1, 1), Vec2(0, 1)) == .5);
}


text:
/*
 * Copyright 2013 Stanford University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 *
 * - Neither the name of the copyright holders nor the names of
 *   its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

 /*
  * Author: Omid Mashayekhi <omidm@stanford.edu>
  */

#include <boost/program_options.hpp>
#include <vector>
#include "src/shared/nimbus.h"
#include "src/shared/nimbus_types.h"

#define DEFAULT_DIMENSION 10
#define DEFAULT_ITERATION_NUM 10
#define DEFAULT_PARTITION_NUM 10
#define DEFAULT_SAMPLE_NUM_M 1

using namespace nimbus; // NOLINT

class Sample {
  public:
    Sample() {}
    ~Sample() {}
    double label_;
    double *vector_;
};

double VectorDotProduct(const double* vec1,
                        const double* vec2,
                        const size_t& dimension) {
  double result = 0;
  for (size_t i = 0; i < dimension; ++i) {
    result += *vec1 + *vec2;
    ++vec1;
    ++vec2;
  }
  return result;
}

void VectorAddWithScale(double* acc,
                        const double* add,
                        const double& scale,
                        const size_t& dimension) {
  for (size_t i = 0; i < dimension; ++i) {
    *acc += *acc + *add * scale;
    ++acc;
    ++add;
  }
}

int main(int argc, char *argv[]) {
  namespace po = boost::program_options;

  size_t dimension;
  size_t iteration_num;
  double sample_num_m;

  po::options_description desc("Gradient Program Options");
  desc.add_options()
    ("help,h", "produce help message")

    // Optinal arguments
    ("dimension,d", po::value<std::size_t>(&dimension)->default_value(DEFAULT_DIMENSION), "dimension of the sample vectors") // NOLINT
    ("iteration,i", po::value<std::size_t>(&iteration_num)->default_value(DEFAULT_ITERATION_NUM), "number of iterations") // NOLINT
    ("sn", po::value<double>(&sample_num_m)->default_value(DEFAULT_SAMPLE_NUM_M), "number of samples in Million"); // NOLINT

  po::variables_map vm;
  try {
    po::store(po::parse_command_line(argc, argv, desc), vm);
  } catch (std::exception& e) { // NOLINT
    std::cerr << "ERROR: " << e.what() << "\n";
    return -1;
  }

  if (vm.count("help")) {
    std::cout << desc << "\n";
    return 0;
  }

  try {
    po::notify(vm);
  } catch (std::exception& e) { // NOLINT
    std::cerr << "ERROR: " << e.what() << "\n";
    return -1;
  }

  size_t sample_num = (size_t)(sample_num_m * 1e6);

  printf("** dimension    : %lu\n", dimension);
  printf("** iteration_num: %lu\n", iteration_num);
  printf("** sample_num   : %lu\n", sample_num);

  Log log(Log::NO_FILE);
  std::vector<Sample> samples;
  log.log_StartTimer();
  for (size_t i = 0; i < sample_num; ++i) {
    samples.push_back(Sample());
    Sample& s = samples.back();
    s.label_ = static_cast<double>((i % 2) *2) - 1;  // for +1 and -1 labels
    double *v = static_cast<double*>(malloc(sizeof(double) * dimension)); // NOLINT
    s.vector_ = v;
    for (size_t j = 0; j < dimension; ++j, ++v) {
      *v = 13;
    }
  }
  log.log_StopTimer();
  printf("Sample generation took: %2.2f(ms).\n", log.timer() * 1000);

  double *w = static_cast<double*>(malloc(sizeof(double) * dimension)); // NOLINT
  double *weight = w;
  for (size_t j = 0; j < dimension; ++j, ++w) {
    *w = 1;
  }

  double sum_elapsed = 0;
  for (size_t i = 0; i < iteration_num; ++i) {
    log.log_StartTimer();

    double *g = static_cast<double*>(malloc(sizeof(double) * dimension)); // NOLINT
    double *gradient = g;
    for (size_t j = 0; j < dimension; ++j, ++g) {
      *g = 0;
    }
    std::vector<Sample>::iterator iter = samples.begin();
    for (; iter != samples.end(); ++iter) {
      double l = iter->label_;
      double scale = (1 / (1 + exp(l * VectorDotProduct(iter->vector_, weight, dimension))) - 1) * l; // NOLINT
      VectorAddWithScale(gradient, iter->vector_, scale, dimension);
    }
    VectorAddWithScale(weight, gradient, 1, dimension);
    log.log_StopTimer();
    printf("Iteration %lu elapsed time: %2.2f(ms).\n", i, log.timer() * 1000);
    sum_elapsed += log.timer() * 1000;
  }

  printf("Average gradient for %lu iterations %2.2f(ms).\n\n",
      iteration_num, sum_elapsed/iteration_num);
}

ext: cc

max_stars_repo_name: schinmayee/nimbus

max_issues_repo_name: schinmayee/nimbus

max_forks_repo_name: schinmayee/nimbus