<commit_before>#include <atomic>
#include <cassert>
#include <cstdint>
#include <cstdio>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

#include <getopt.h>
#include <semaphore.h>

static void print_usage(FILE* out, const char* const name) {
  fprintf(out, "Usage: %s [options]\n", name);
  fprintf(out, "option:\n");
  fprintf(out, "\t-t {number}\tthe number of threads (default is 8)\n");
  fprintf(out, "\t-n {number}\tthe number to add (default is 1,000,000\n");
  fprintf(out, "\t-l [semaphore|filter|cpp11|buggy|atomic]\tthe type of lock (default is semaphore)\n");
  fprintf(out, "\t-h\tprint this message\n");
}

enum class lock_type {
  semaphore, filter, cpp11, buggy, atomic
};

struct config {
  uint32_t number_of_threads;
  uint32_t number_to_add;
  ::lock_type lock_type;

  config()
      : number_of_threads(8),
      number_to_add(1000000),
      lock_type(::lock_type::semaphore) {
  }

  config(uint32_t number_of_threads, uint32_t number_to_add, ::lock_type lock_type)
      : number_of_threads(number_of_threads),
      number_to_add(number_to_add),
      lock_type(lock_type) {
  }
};

static config parse_argument(int argc, char * const argv[]) {
  config config;

  int opt;
  while ((opt = getopt(argc, argv, "ht:n:l:")) != -1) {
  switch (opt) {
  case 't': {
    int opt_number_of_threads = atoi(optarg);
    if (opt_number_of_threads <= 0) {
      print_usage(stderr, argv[0]);
      exit(-1);
    }
    config.number_of_threads = static_cast<uint32_t>(opt_number_of_threads);
    break;
  }
  case 'n': {
    int opt_number_to_add = atoi(optarg);
    if (opt_number_to_add <= 0) {
      print_usage(stderr, argv[0]);
      exit(-1);
    }
    config.number_to_add = static_cast<uint32_t>(opt_number_to_add);
    break;
  }
  case 'l': {
    std::string opt_lock_type(optarg);
    if (opt_lock_type == "semaphore") {
      config.lock_type = ::lock_type::semaphore;
    } else if (opt_lock_type == "filter") {
      config.lock_type = ::lock_type::filter;
    } else if (opt_lock_type == "cpp11") {
      config.lock_type = ::lock_type::cpp11;
    } else if (opt_lock_type == "buggy") {
      config.lock_type = ::lock_type::buggy;
    } else if (opt_lock_type == "atomic") {
      config.lock_type = ::lock_type::atomic;
    } else {
      print_usage(stderr, argv[0]);
      exit(-1);
    }
    break;
  }
  case 'h': {
    print_usage(stdout, argv[0]);
    exit(0);
    break;
  }
  default:
    break;
  }
  }

  return config;
}

static uint32_t g_count =0;
static std::mutex mutex;
void increase_with_cpp11(uint32_t n) {
  for (uint32_t i = 0; i < n; i += 1) {
    std::lock_guard<std::mutex> lock(mutex);
    g_count += 1;
  }
}

static sem_t semaphore;
void increase_with_semaphore(uint32_t n) {
  for (uint32_t i = 0; i < n; i += 1) {
    sem_wait(&semaphore);
    g_count += 1;
    sem_post(&semaphore);
  }
}

void increase_with_buggy_implementation(uint32_t n) {
  for (uint32_t i = 0; i < n; i += 1) {
    g_count += 1;
  }
}

static std::atomic<uint32_t> g_atomic_count;
void increase_with_atomic(uint32_t n) {
  for (uint32_t i = 0; i < n; i += 1) {
    g_atomic_count += 1;
  }
}

int main(int argc, char * const argv[]) {
  const auto&& config = parse_argument(argc, argv);

  std::vector<std::thread> threads;
  switch (config.lock_type) {
  case ::lock_type::cpp11: {
    std::mutex mutex;
    for (size_t i = 0; i < config.number_of_threads; i += 1) {
      threads.emplace_back(increase_with_cpp11, config.number_to_add / config.number_of_threads);
    }
    break;
  }
  case ::lock_type::semaphore: {
    sem_init(&semaphore, 0, 1);
    for (size_t i = 0; i < config.number_of_threads; i += 1) {
      threads.emplace_back(increase_with_semaphore, config.number_to_add / config.number_of_threads);
    }
    break;
  }
  case ::lock_type::buggy: {
    for (size_t i = 0; i < config.number_of_threads; i += 1) {
      threads.emplace_back(increase_with_buggy_implementation, config.number_to_add / config.number_of_threads);
    }
    break;
  }
  case ::lock_type::atomic: {
    for (size_t i = 0; i < config.number_of_threads; i += 1) {
      threads.emplace_back(increase_with_atomic, config.number_to_add / config.number_of_threads);
    }
    break;
  }
  default:
    assert(false);
    break;
  }

  for (auto& thread : threads) {
    thread.join();
  }

  if (config.lock_type == ::lock_type::atomic) {
    printf("Count: %u (%s)\n", static_cast<uint32_t>(g_atomic_count), g_atomic_count.is_lock_free() ? "true" : "false");
  } else {
    printf("Count: %u\n", g_count);
  }

  return 0;
}
<commit_msg>[C++] Implement filter lock.<commit_after>#include <atomic>
#include <cassert>
#include <cstdint>
#include <cstdio>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

#include <getopt.h>
#include <semaphore.h>

#if defined(__GNUC__)
#define INLINE inline __attribute__((__always_inline__))
#elif defined(_MSC_VER)
#define INLINE __forceinline
#else
#define INLINE inline
#endif

static INLINE void memory_fence(void)
{
#if defined(__GNUC__)
    __sync_synchronize();
#elif defined(__llvm__)
    __sync_synchronize();
#elif defined(_MSC_VER)
    _mm_mfence();
#else
#error This compiler is not supported.
#endif
}

static void print_usage(FILE* out, const char* const name) {
  fprintf(out, "Usage: %s [options]\n", name);
  fprintf(out, "option:\n");
  fprintf(out, "\t-t {number}\tthe number of threads (default is 8)\n");
  fprintf(out, "\t-n {number}\tthe number to add (default is 1,000,000\n");
  fprintf(out, "\t-l [semaphore|filter|cpp11|buggy|atomic]\tthe type of lock (default is semaphore)\n");
  fprintf(out, "\t-h\tprint this message\n");
}

enum class lock_type {
  semaphore, filter, cpp11, buggy, atomic
};

struct config {
  uint32_t number_of_threads;
  uint32_t number_to_add;
  ::lock_type lock_type;

  config()
      : number_of_threads(8),
      number_to_add(1000000),
      lock_type(::lock_type::semaphore) {
  }

  config(uint32_t number_of_threads, uint32_t number_to_add, ::lock_type lock_type)
      : number_of_threads(number_of_threads),
      number_to_add(number_to_add),
      lock_type(lock_type) {
  }
};

static config parse_argument(int argc, char * const argv[]) {
  config config;

  int opt;
  while ((opt = getopt(argc, argv, "ht:n:l:")) != -1) {
  switch (opt) {
  case 't': {
    int opt_number_of_threads = atoi(optarg);
    if (opt_number_of_threads <= 0) {
      print_usage(stderr, argv[0]);
      exit(-1);
    }
    config.number_of_threads = static_cast<uint32_t>(opt_number_of_threads);
    break;
  }
  case 'n': {
    int opt_number_to_add = atoi(optarg);
    if (opt_number_to_add <= 0) {
      print_usage(stderr, argv[0]);
      exit(-1);
    }
    config.number_to_add = static_cast<uint32_t>(opt_number_to_add);
    break;
  }
  case 'l': {
    std::string opt_lock_type(optarg);
    if (opt_lock_type == "semaphore") {
      config.lock_type = ::lock_type::semaphore;
    } else if (opt_lock_type == "filter") {
      config.lock_type = ::lock_type::filter;
    } else if (opt_lock_type == "cpp11") {
      config.lock_type = ::lock_type::cpp11;
    } else if (opt_lock_type == "buggy") {
      config.lock_type = ::lock_type::buggy;
    } else if (opt_lock_type == "atomic") {
      config.lock_type = ::lock_type::atomic;
    } else {
      print_usage(stderr, argv[0]);
      exit(-1);
    }
    break;
  }
  case 'h': {
    print_usage(stdout, argv[0]);
    exit(0);
    break;
  }
  default:
    break;
  }
  }

  return config;
}

static uint32_t g_count =0;

static uint32_t* filter_level;
static uint32_t* filter_victim;
static uint32_t filter_n;

static bool filter_condition(const uint32_t& tid, const uint32_t& L) {
  for (uint32_t k = 0; k < filter_n; k += 1) {
    if (k == tid) {
      continue;
    }
    memory_fence();
    if (filter_level[k] >= L) {
      return true;
    }
  }
  return false;
}

static void filter_lock(uint32_t tid) {
  for (uint32_t L = 1; L < filter_n; L += 1) {
    filter_level[tid] = L;
    filter_victim[L] = tid;

    while (true) {
      if (!filter_condition(tid, L)) {
        break;
      }
      memory_fence();
      if (filter_victim[L] != tid) {
        break;
      }
    }
  }
}

static void filter_unlock(uint32_t tid) {
  filter_level[tid] = 0;
}

void increase_with_filter(uint32_t tid, uint32_t n) {
  for (uint32_t i = 0; i < n; i += 1) {
    filter_lock(tid);
    g_count += 1;
    filter_unlock(tid);
  }
}

static std::mutex mutex;
void increase_with_cpp11(uint32_t n) {
  for (uint32_t i = 0; i < n; i += 1) {
    std::lock_guard<std::mutex> lock(mutex);
    g_count += 1;
  }
}

static sem_t semaphore;
void increase_with_semaphore(uint32_t n) {
  for (uint32_t i = 0; i < n; i += 1) {
    sem_wait(&semaphore);
    g_count += 1;
    sem_post(&semaphore);
  }
}

void increase_with_buggy_implementation(uint32_t n) {
  for (uint32_t i = 0; i < n; i += 1) {
    g_count += 1;
  }
}

static std::atomic<uint32_t> g_atomic_count;
void increase_with_atomic(uint32_t n) {
  for (uint32_t i = 0; i < n; i += 1) {
    g_atomic_count += 1;
  }
}

int main(int argc, char * const argv[]) {
  const auto&& config = parse_argument(argc, argv);

  std::vector<std::thread> threads;
  switch (config.lock_type) {
  case ::lock_type::filter: {
    filter_n = config.number_of_threads;
    filter_level = new uint32_t[filter_n];
    filter_victim = new uint32_t[filter_n];
    for (size_t i = 0; i < config.number_of_threads; i += 1) {
      threads.emplace_back(increase_with_filter, i, config.number_to_add / config.number_of_threads);
    }
    break;
  }
  case ::lock_type::cpp11: {
    std::mutex mutex;
    for (size_t i = 0; i < config.number_of_threads; i += 1) {
      threads.emplace_back(increase_with_cpp11, config.number_to_add / config.number_of_threads);
    }
    break;
  }
  case ::lock_type::semaphore: {
    sem_init(&semaphore, 0, 1);
    for (size_t i = 0; i < config.number_of_threads; i += 1) {
      threads.emplace_back(increase_with_semaphore, config.number_to_add / config.number_of_threads);
    }
    break;
  }
  case ::lock_type::buggy: {
    for (size_t i = 0; i < config.number_of_threads; i += 1) {
      threads.emplace_back(increase_with_buggy_implementation, config.number_to_add / config.number_of_threads);
    }
    break;
  }
  case ::lock_type::atomic: {
    for (size_t i = 0; i < config.number_of_threads; i += 1) {
      threads.emplace_back(increase_with_atomic, config.number_to_add / config.number_of_threads);
    }
    break;
  }
  default:
    assert(false);
    break;
  }

  for (auto& thread : threads) {
    thread.join();
  }

  if (config.lock_type == ::lock_type::atomic) {
    printf("Count: %u (%s)\n", static_cast<uint32_t>(g_atomic_count), g_atomic_count.is_lock_free() ? "true" : "false");
  } else {
    printf("Count: %u\n", g_count);
  }

  return 0;
}
<|endoftext|>


<commit_before><commit_msg>ATO-396 - formula browser - using automatic intendation from CLION<commit_after><|endoftext|>


<commit_before><commit_msg>Use real A,Z in beam energy calculation<commit_after><|endoftext|>


<commit_before>#include "func.hpp"
#include "params.hpp"
#include "../loader/interpreter/tverification.hpp"
#include "../loader/interpreter/verifier.hpp"

namespace wrd {

    WRD_DEF_ME(func)

    wbool me::canRun(const ucontainable& args) const {
        const params& ps = getParams();
        if(args.len() != ps.len()) return false;

        int n = 0;
        for(const auto& e : args)
            if(!e.getEvalType().isImpli(ps[n++].getOrgType()))
                return false;

        return true;
    }

    const params& me::getParams() const {
        static params inner;
        return inner;
    }

    WRD_VERIFY({
        WRD_DI("verify: func: param check");

        /*for(const param& p : it.getParams()) {
        }*/
    })
}
<commit_msg>wrd: fix: core crashed because of NPE<commit_after>#include "func.hpp"
#include "params.hpp"
#include "../loader/interpreter/tverification.hpp"
#include "../loader/interpreter/verifier.hpp"

namespace wrd {

    WRD_DEF_ME(func)

    wbool me::canRun(const ucontainable& args) const {
        const params& ps = getParams();
        if(args.len() != ps.len()) return false;

        int n = 0;
        for(const auto& e : args) {
            const wtype& t = e.getEvalType();
            if(nul(t)) return WRD_W("t == null"), false;
            if(!t.isImpli(ps[n++].getOrgType()))
                return false;
        }

        return true;
    }

    const params& me::getParams() const {
        static params inner;
        return inner;
    }

    WRD_VERIFY({
        WRD_DI("verify: func: param check");

        /*for(const param& p : it.getParams()) {
        }*/
    })
}
<|endoftext|>


<commit_before>//g++ *.cpp -lpthread -lwiringPi -std=c++11
//LATER MET GUI MAKEFILE <sudo make>

#include "Sensor.h"
#include "I2C.h"
#include "Log.h"
#include "Camera.h"
#include "Light.h"
#include "MotionSensor.h"
#include "PressureSensor.h"
#define I2CLOC "/dev/i2c-1"// <-- this is the real I2C device you need with the scale model
///#define I2CLOC "/dev/simudrv"
#define LOG "Slaaplog.txt"

#include <vector>
#include <iostream>
#include <wiringPi.h>  //compile with -lwiringPi

using namespace std;

vector<Sensor*> sensors;    //Vector of the sensors
vector<Light*> lights;      //Vector of the lights
Camera& cam;                //Pointer to the camera

int sumActive(int active[]) {
	int sum=0;
	for(int i=0;i<sizeof(active[])/sizeof(active[0]);i++)
		sum+=active[i];
	return sum;
}

/*Sets the camera*/
void setCam(bool b){
    cam.setCamera(b);
}

int main() {
	wiringPiSetupGpio();
	Light x(22);
	I2CCom i2c(I2CLOC);     //the i2c to communicate with sensors
	MotionSensor s1(0x05,i2c);
	Log log(LOG);
	PressureSensor s2(0x06, i2c, log);

	sensors.push_back(&s1);
	sensors.push_back(&s2);

	lights.push_back(&x);
	int i;

	for(i=0;i<sensors.capacity();i++); // create an array equal to the amount of sensors
		int active[i];

	for(i=0;i<sensors.capacity();i++) { // set all sensors as inactive
		active[i]=0;
	}
	int active=0;

	while(1) {
		for(i=0;i<sensors.capacity();i++) // For every sensor
			if(sensors[i]->Check()) { // Call their check function
				active[i]=1; // And if the check is positive (returns true).
				//TODO ENABLE LIGHTS
			} else active[i]=0;
		if(sumActive(active)==0) {
			cout<<"uhoh"<<endl;
			// Guard.sendAlert();
		}
		for(i=0;i<lights.capacity();i++) // For every light
			lights[i]->Check(); // Check if timer expired yet
	}
}
<commit_msg>Code cleanup<commit_after>//g++ *.cpp -lpthread -lwiringPi -std=c++11
//LATER MET GUI MAKEFILE <sudo make>

#include "Sensor.h"
#include "I2C.h"
#include "Log.h"
#include "Camera.h"
#include "Light.h"
#include "MotionSensor.h"
#include "PressureSensor.h"
#define I2CLOC "/dev/i2c-1"// <-- this is the real I2C device you need with the scale model
///#define I2CLOC "/dev/simudrv"
#define LOG "Slaaplog.txt"

#include <vector>
#include <iostream>
#include <wiringPi.h>  //compile with -lwiringPi

using namespace std;

vector<Sensor*> sensors;    //Vector of the sensors
vector<Light*> lights;      //Vector of the lights
vector<int> values;         //Vector of the values from the sensors
vector<int> active;
Camera& cam;                //Pointer to the camera

int sumActive(int active[]) {
	int sum=0;
	for(int i=0;i<sizeof(active[])/sizeof(active[0]);i++)
		sum+=active[i];
	return sum;
}

void setCam(bool b);

void init();

int main() {

    while(1) {
        for(i=0;i<sensors.capacity();i++) // For every sensor
            if(sensors[i]->Check()) { // Call their check function
				active[i]=1; // And if the check is positive (returns true).
				//TODO ENABLE LIGHTS
			} else active[i]=0;
		if(sumActive(active)==0) {
			cout<<"uhoh"<<endl;
			// Guard.sendAlert();
		}
		for(i=0;i<lights.capacity();i++) // For every light
			lights[i]->Check(); // Check if timer expired yet
	}
}

/*Init for the main*/
void init() {
    wiringPiSetupGpio();
    Light x(22);
    I2CCom i2c(I2CLOC);     //the i2c to communicate with sensors
    MotionSensor s1(0x05,i2c);
    Log log(LOG);
    PressureSensor s2(0x06, i2c, log);

    sensors.push_back(&s1);
    sensors.push_back(&s2);

    lights.push_back(&x);

    active.resize(sensors.sizeof);
    values.resize(sensors.sizeof);
}

/*Sets the camera*/
void setCam(bool b){
    cam.setCamera(b);
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (C) 2014 Denis Rotanov <drotanov@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 ******************************************************************************/

#pragma once

//==============================================================================
#define MFLECT_CAST(WHAT, TO)                                                  \
  mflect::cast<TO>(WHAT, TO::type_info_static())                               \

//==============================================================================
#define MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BEGIN_(TYPE)                     \
  class type_info_##TYPE : public mflect::type_info                            \
  {                                                                            \
  public:                                                                      \

//==============================================================================
#define MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BASE_(TYPE)                      \
    type_info_##TYPE()                                                         \
    {                                                                          \
      register_type_info_(#TYPE, this);                                        \
    }                                                                          \
                                                                               \
    virtual void* make_new() const                                             \
    {                                                                          \
      return mflect::make<TYPE>::instance();                                   \
    }                                                                          \
                                                                               \
    virtual void make_delete(void* instance) const                             \
    {                                                                          \
      delete static_cast<TYPE*>(instance);                                     \
    }                                                                          \
                                                                               \
    virtual const char* name() const                                           \
    {                                                                          \
      return #TYPE;                                                            \
    }                                                                          \
                                                                               \
    virtual bool is_integral() const                                           \
    {                                                                          \
        return mflect::is_integral<TYPE>::value;                               \
    }                                                                          \
                                                                               \
    virtual void from_string(void* instance, const std::string& value) const   \
    {                                                                          \
      mflect::TypeInfoStringToTypeHelper<TYPE>::StringToType(value,            \
        static_cast<TYPE*>(instance));                                         \
    }                                                                          \
                                                                               \
    virtual std::string to_string(void* instance) const                        \
    {                                                                          \
      return mflect::TypeInfoTypeToStringHelper<TYPE>::                        \
        TypeToString(static_cast<TYPE*>(instance));                            \
    }                                                                          \
                                                                               \
    virtual mflect::property_info* property(const std::string& name) const     \
    {                                                                          \
      return properties_[name];                                                \
    }                                                                          \
                                                                               \
    virtual std::unordered_map<std::string, mflect::property_info*>&           \
      properties() const                                                       \
    {                                                                          \
      return properties_;                                                      \
    }                                                                          \

//==============================================================================
  static type_info_##TYPE instance_;                                           \
#define MFLECT_INTERNAL_TYPE_INFO_DECLARATION_END_(TYPE)                       \
  static std::unordered_map<std::string, mflect::property_info*> properties_;  \
};                                                                             \
                                                                               \
type_info_##TYPE type_info_##TYPE::instance_;                                  \
std::unordered_map<std::string, mflect::property_info*>                        \
  type_info_##TYPE::properties_;                                               \
                                                                               \

//==============================================================================
#define MFLECT_TYPE_INFO_DECLARE(TYPE)                                         \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BEGIN_(TYPE)                           \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BASE_(TYPE)                            \
                                                                               \
  virtual type_info* type_info_run_time(const void* /*instance*/) const        \
  {                                                                            \
      return type_info_##TYPE::instance();                                     \
  }                                                                            \
                                                                               \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_END_(TYPE)                             \

//==============================================================================
#define MFLECT_TYPE_INFO_DECLARE_DERIVED(TYPE_DERIVED, TYPE_BASE)              \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BEGIN_(TYPE_DERIVED)                   \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BASE_(TYPE_DERIVED)                    \
                                                                               \
  virtual const char* base_name() const                                        \
  {                                                                            \
    return #TYPE_BASE;                                                         \
  }                                                                            \
                                                                               \
  virtual type_info* type_info_run_time(const void* instance) const            \
  {                                                                            \
    return static_cast<const TYPE_DERIVED*>(instance)->type_info_run_time();   \
  }                                                                            \
                                                                               \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_END_(TYPE_DERIVED)                     \

//==============================================================================
#define MFLECT_INTERNAL_INJECT_TYPE_INFO_BASE_(TYPE)                           \
  public:                                                                      \
    virtual mflect::type_info* type_info_run_time() const                      \
    {                                                                          \
      static mflect::type_info* typeInfo_                                      \
        = mflect::type_info::find_type_info(#TYPE);                            \
      return typeInfo_;                                                        \
    }                                                                          \
                                                                               \
    inline static mflect::type_info* type_info_static()                        \
    {                                                                          \
      static mflect::type_info* typeInfo_                                      \
        = mflect::type_info::find_type_info(#TYPE);                            \
      return typeInfo_;                                                        \
    }                                                                          \
                                                                               \
    private:                                                                   \

//==============================================================================
#define MFLECT_INJECT_TYPE_INFO(TYPE)                                          \
  MFLECT_INTERNAL_INJECT_TYPE_INFO_BASE_(TYPE)                                 \

//==============================================================================
#define MFLECT_INJECT_TYPE_INFO_DERIVED(TYPE_DERIVED, TYPE_BASE)               \
  public:                                                                      \
    typedef TYPE_BASE base_type;                                               \
                                                                               \
  MFLECT_INTERNAL_INJECT_TYPE_INFO_BASE_(TYPE_DERIVED)

//==============================================================================
#define MFLECT_INJECT_PROPERTY(TYPE, NAME)                                     \
  public:                                                                      \
    TYPE Get##NAME() const { return NAME##_; }                                 \
    void Set##NAME(const TYPE& value) { NAME##_ = value; }                     \
                                                                               \
  private:                                                                     \
    TYPE NAME##_;                                                              \

//==============================================================================
#define MFLECT_INJECT_VECTOR_PROPERTY(TYPE, NAME)                              \
  public:                                                                      \
    TYPE Get##NAME(unsigned index) const { return NAME[index]; }               \
    void Push##NAME(const TYPE& value) { NAME.push_back(value); }              \
    unsigned Get##NAME##Count() const { return NAME.size(); }                  \
    void Clear##NAME() { NAME.clear(); }                                       \
                                                                               \
  private:                                                                     \
    std::vector<TYPE> NAME;                                                    \

//==============================================================================
#define MFLECT_INJECT_VECTOR_PTR_PROPERTY(TYPE, NAME)                          \
  public:                                                                      \
    TYPE* Get##NAME(unsigned index) const { return NAME[index]; }              \
    void Push##NAME(TYPE* value) { NAME.push_back(value); }                    \
    unsigned Get##NAME##Count() const { return NAME.size(); }                  \
    void Clear##NAME() { NAME.clear(); }                                       \
                                                                               \
  private:                                                                     \
    std::vector<TYPE*> NAME;                                                   \

<commit_msg>Prevent static variable initialization order fiasco bug<commit_after>/*******************************************************************************
 * Copyright (C) 2014 Denis Rotanov <drotanov@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 ******************************************************************************/

#pragma once

//==============================================================================
#define MFLECT_CAST(WHAT, TO)                                                  \
  mflect::cast<TO>(WHAT, TO::type_info_static())                               \

//==============================================================================
#define MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BEGIN_(TYPE)                     \
  class type_info_##TYPE : public mflect::type_info                            \
  {                                                                            \
  public:                                                                      \

//==============================================================================
#define MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BASE_(TYPE)                      \
    type_info_##TYPE()                                                         \
    {                                                                          \
      register_type_info_(#TYPE, this);                                        \
    }                                                                          \
                                                                               \
    virtual void* make_new() const                                             \
    {                                                                          \
      return mflect::make<TYPE>::instance();                                   \
    }                                                                          \
                                                                               \
    virtual void make_delete(void* instance) const                             \
    {                                                                          \
      delete static_cast<TYPE*>(instance);                                     \
    }                                                                          \
                                                                               \
    virtual const char* name() const                                           \
    {                                                                          \
      return #TYPE;                                                            \
    }                                                                          \
                                                                               \
    virtual bool is_integral() const                                           \
    {                                                                          \
        return mflect::is_integral<TYPE>::value;                               \
    }                                                                          \
                                                                               \
    virtual void from_string(void* instance, const std::string& value) const   \
    {                                                                          \
      mflect::TypeInfoStringToTypeHelper<TYPE>::StringToType(value,            \
        static_cast<TYPE*>(instance));                                         \
    }                                                                          \
                                                                               \
    virtual std::string to_string(void* instance) const                        \
    {                                                                          \
      return mflect::TypeInfoTypeToStringHelper<TYPE>::                        \
        TypeToString(static_cast<TYPE*>(instance));                            \
    }                                                                          \
                                                                               \
    virtual mflect::property_info* property(const std::string& name) const     \
    {                                                                          \
      return properties_[name];                                                \
    }                                                                          \
                                                                               \
    virtual std::unordered_map<std::string, mflect::property_info*>&           \
      properties() const                                                       \
    {                                                                          \
      return properties_;                                                      \
    }                                                                          \
                                                                               \
    static type_info_##TYPE* instance()                                        \
    {                                                                          \
      static type_info_##TYPE instance_;                                       \
      return &instance_;                                                       \
    }                                                                          \

//==============================================================================
#define MFLECT_INTERNAL_TYPE_INFO_DECLARATION_END_(TYPE)                       \
private:                                                                       \
  static type_info_##TYPE* instance_ptr_;                                      \
  static std::unordered_map<std::string, mflect::property_info*> properties_;  \
};                                                                             \
                                                                               \
type_info_##TYPE* type_info_##TYPE::instance_ptr_                              \
  =  type_info_##TYPE::instance();                                             \
std::unordered_map<std::string, mflect::property_info*>                        \
  type_info_##TYPE::properties_;                                               \
                                                                               \

//==============================================================================
#define MFLECT_TYPE_INFO_DECLARE(TYPE)                                         \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BEGIN_(TYPE)                           \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BASE_(TYPE)                            \
                                                                               \
  virtual type_info* type_info_run_time(const void* /*instance*/) const        \
  {                                                                            \
      return type_info_##TYPE::instance();                                     \
  }                                                                            \
                                                                               \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_END_(TYPE)                             \

//==============================================================================
#define MFLECT_TYPE_INFO_DECLARE_DERIVED(TYPE_DERIVED, TYPE_BASE)              \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BEGIN_(TYPE_DERIVED)                   \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_BASE_(TYPE_DERIVED)                    \
                                                                               \
  virtual const char* base_name() const                                        \
  {                                                                            \
    return #TYPE_BASE;                                                         \
  }                                                                            \
                                                                               \
  virtual type_info* type_info_run_time(const void* instance) const            \
  {                                                                            \
    return static_cast<const TYPE_DERIVED*>(instance)->type_info_run_time();   \
  }                                                                            \
                                                                               \
  MFLECT_INTERNAL_TYPE_INFO_DECLARATION_END_(TYPE_DERIVED)                     \

//==============================================================================
#define MFLECT_INTERNAL_INJECT_TYPE_INFO_BASE_(TYPE)                           \
  public:                                                                      \
    virtual mflect::type_info* type_info_run_time() const                      \
    {                                                                          \
      static mflect::type_info* typeInfo_                                      \
        = mflect::type_info::find_type_info(#TYPE);                            \
      return typeInfo_;                                                        \
    }                                                                          \
                                                                               \
    inline static mflect::type_info* type_info_static()                        \
    {                                                                          \
      static mflect::type_info* typeInfo_                                      \
        = mflect::type_info::find_type_info(#TYPE);                            \
      return typeInfo_;                                                        \
    }                                                                          \
                                                                               \
    private:                                                                   \

//==============================================================================
#define MFLECT_INJECT_TYPE_INFO(TYPE)                                          \
  MFLECT_INTERNAL_INJECT_TYPE_INFO_BASE_(TYPE)                                 \

//==============================================================================
#define MFLECT_INJECT_TYPE_INFO_DERIVED(TYPE_DERIVED, TYPE_BASE)               \
  public:                                                                      \
    typedef TYPE_BASE base_type;                                               \
                                                                               \
  MFLECT_INTERNAL_INJECT_TYPE_INFO_BASE_(TYPE_DERIVED)

//==============================================================================
#define MFLECT_INJECT_PROPERTY(TYPE, NAME)                                     \
  public:                                                                      \
    TYPE Get##NAME() const { return NAME##_; }                                 \
    void Set##NAME(const TYPE& value) { NAME##_ = value; }                     \
                                                                               \
  private:                                                                     \
    TYPE NAME##_;                                                              \

//==============================================================================
#define MFLECT_INJECT_VECTOR_PROPERTY(TYPE, NAME)                              \
  public:                                                                      \
    TYPE Get##NAME(unsigned index) const { return NAME[index]; }               \
    void Push##NAME(const TYPE& value) { NAME.push_back(value); }              \
    unsigned Get##NAME##Count() const { return NAME.size(); }                  \
    void Clear##NAME() { NAME.clear(); }                                       \
                                                                               \
  private:                                                                     \
    std::vector<TYPE> NAME;                                                    \

//==============================================================================
#define MFLECT_INJECT_VECTOR_PTR_PROPERTY(TYPE, NAME)                          \
  public:                                                                      \
    TYPE* Get##NAME(unsigned index) const { return NAME[index]; }              \
    void Push##NAME(TYPE* value) { NAME.push_back(value); }                    \
    unsigned Get##NAME##Count() const { return NAME.size(); }                  \
    void Clear##NAME() { NAME.clear(); }                                       \
                                                                               \
  private:                                                                     \
    std::vector<TYPE*> NAME;                                                   \

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbConfigurationManager.h"

#include "otbMacro.h"
#include "otbLogger.h"

#include "itkMultiThreader.h"
#include "itksys/SystemTools.hxx"

#ifdef _OPENMP
#include <omp.h>
#endif

#include <cstdlib>
#include <algorithm>
#include <string>

namespace otb
{

std::string ConfigurationManager::GetDEMDirectory()
{
  std::string svalue;
  itksys::SystemTools::GetEnv("OTB_DEM_DIRECTORY",svalue);
  return svalue;
}

std::string ConfigurationManager::GetGeoidFile()
{
  std::string svalue;
  itksys::SystemTools::GetEnv("OTB_GEOID_FILE",svalue);
  return svalue;
}

ConfigurationManager::RAMValueType ConfigurationManager::GetMaxRAMHint()
{
  std::string svalue;

  RAMValueType value = 128;

  if(itksys::SystemTools::GetEnv("OTB_MAX_RAM_HINT",svalue))
    {

    unsigned long int tmp = strtoul(svalue.c_str(),nullptr,10);

    if(tmp)
      {
      value = static_cast<RAMValueType>(tmp);
      }
    }

  return value;
}

itk::LoggerBase::PriorityLevelType ConfigurationManager::GetLoggerLevel()
{
  std::string svalue;

  // Default value is INFO
  itk::LoggerBase::PriorityLevelType level = itk::LoggerBase::INFO;

  if(itksys::SystemTools::GetEnv("OTB_LOGGER_LEVEL",svalue))
    {
    if(svalue.compare("DEBUG") == 0)
      {
      level = itk::LoggerBase::DEBUG;
      }
    else if(svalue.compare("INFO") == 0)
      {
      level = itk::LoggerBase::INFO;
      }
    else if(svalue.compare("WARNING") == 0)
      {
      level = itk::LoggerBase::WARNING;
      }
    else if(svalue.compare("CRITICAL") == 0)
      {
      level = itk::LoggerBase::CRITICAL;
      }
    else
      {
      otbLogMacro(Error,<<"Unknown value for OTB_LOGGER_LEVEL_MACRO. Possible values are DEBUG, INFO, WARNING, CRITICAL.");
      }
    }
  return level;
}

int ConfigurationManager::InitOpenMPThreads()
{
  int ret = 1;
#ifdef _OPENMP
  ret = itk::MultiThreader::GetGlobalDefaultNumberOfThreads();
  omp_set_num_threads(ret);
#endif
  return ret;
}

}
<commit_msg>ENH: increase default ram limit to 256MB<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbConfigurationManager.h"

#include "otbMacro.h"
#include "otbLogger.h"

#include "itkMultiThreader.h"
#include "itksys/SystemTools.hxx"

#ifdef _OPENMP
#include <omp.h>
#endif

#include <cstdlib>
#include <algorithm>
#include <string>

namespace otb
{

std::string ConfigurationManager::GetDEMDirectory()
{
  std::string svalue;
  itksys::SystemTools::GetEnv("OTB_DEM_DIRECTORY",svalue);
  return svalue;
}

std::string ConfigurationManager::GetGeoidFile()
{
  std::string svalue;
  itksys::SystemTools::GetEnv("OTB_GEOID_FILE",svalue);
  return svalue;
}

ConfigurationManager::RAMValueType ConfigurationManager::GetMaxRAMHint()
{
  std::string max_ram_hint;
  if (itksys::SystemTools::GetEnv("OTB_MAX_RAM_HINT", max_ram_hint))
  {
    return std::stoul(max_ram_hint);
  }
  else
  {
    // Default value
    return 256;
  }
}

itk::LoggerBase::PriorityLevelType ConfigurationManager::GetLoggerLevel()
{
  std::string svalue;

  // Default value is INFO
  itk::LoggerBase::PriorityLevelType level = itk::LoggerBase::INFO;

  if(itksys::SystemTools::GetEnv("OTB_LOGGER_LEVEL",svalue))
    {
    if(svalue.compare("DEBUG") == 0)
      {
      level = itk::LoggerBase::DEBUG;
      }
    else if(svalue.compare("INFO") == 0)
      {
      level = itk::LoggerBase::INFO;
      }
    else if(svalue.compare("WARNING") == 0)
      {
      level = itk::LoggerBase::WARNING;
      }
    else if(svalue.compare("CRITICAL") == 0)
      {
      level = itk::LoggerBase::CRITICAL;
      }
    else
      {
      otbLogMacro(Error,<<"Unknown value for OTB_LOGGER_LEVEL_MACRO. Possible values are DEBUG, INFO, WARNING, CRITICAL.");
      }
    }
  return level;
}

int ConfigurationManager::InitOpenMPThreads()
{
  int ret = 1;
#ifdef _OPENMP
  ret = itk::MultiThreader::GetGlobalDefaultNumberOfThreads();
  omp_set_num_threads(ret);
#endif
  return ret;
}

}
<|endoftext|>


<commit_before>#pragma once

#include <string>
#include <string_view>
#include <vector>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <iterator>
#include <utility>
#include <initializer_list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <functional>
#include <cassert>

#include "acmacs-base/to-string.hh"

// ----------------------------------------------------------------------

namespace string
{
      // ----------------------------------------------------------------------

    inline std::string first_letter_of_words(std::string s)
    {
        std::string result;
        bool add = true;
        for (char c: s) {
            if (c == ' ') {
                add = true;
            }
            else if (add) {
                result.push_back(c);
                add = false;
            }
        }
        return result;
    }

      // ----------------------------------------------------------------------

    namespace _internal {
        template <typename InputIterator, typename Source> inline std::pair<InputIterator, InputIterator> strip_begin_end(Source& source)
        {
            auto predicate = [](auto c) { return std::isspace(c); }; // have to use lambda, other compiler cannot infer Predicate type from isspace
            auto e = std::find_if_not(source.rbegin(), source.rend(), predicate);
            auto b = std::find_if_not(source.begin(), e.base(), predicate);
            return std::make_pair(b, e.base());
        }
    } // namespace _internal

    // inline std::string& strip(std::string& source)
    // {
    //     auto be = _internal::strip_begin_end<std::string::iterator>(source);
    //     source.erase(be.second, source.end()); // erase at the end first
    //     source.erase(source.begin(), be.first); // invalidates be.second!
    //     return source;
    // }

    // inline std::string strip(std::string&& source)
    // {
    //     auto be = _internal::strip_begin_end<std::string::iterator>(source);
    //     source.erase(be.second, source.end()); // erase at the end first
    //     source.erase(source.begin(), be.first); // invalidates be.second!
    //     return source;
    // }

    inline std::string strip(std::string source)
    {
        auto be = _internal::strip_begin_end<std::string::const_iterator>(source);
        return std::string(be.first, be.second);
    }

      // ----------------------------------------------------------------------

    inline std::string replace(std::string source, std::string look_for, std::string replace_with)
    {
        std::string result;
        std::string::size_type start = 0;
        while (true) {
            const auto pos = source.find(look_for, start);
            if (pos != std::string::npos) {
                result.append(source.begin() + static_cast<std::string::difference_type>(start), source.begin() + static_cast<std::string::difference_type>(pos));
                result.append(replace_with);
                start = pos + look_for.size();
            }
            else {
                result.append(source.begin() + static_cast<std::string::difference_type>(start), source.end());
                break;
            }
        }
        return result;
    }

      // ----------------------------------------------------------------------

    namespace _internal
    {
        template <typename Iter> inline std::string transform(Iter first, Iter last, std::function<char (char)> func)
        {
            std::string result;
            std::transform(first, last, std::back_inserter(result), func);
            return result;
        }
    }

    template <typename S> inline std::string lower(const S& source) { return _internal::transform(source.begin(), source.end(), ::tolower); }
    inline std::string lower(const char* source) { return _internal::transform(source, source + std::strlen(source), ::tolower); }
    inline std::string lower(char* source) { return lower(const_cast<const char*>(source)); }

    template <typename S> inline std::string upper(const S& source) { return _internal::transform(source.begin(), source.end(), ::toupper); }
    inline std::string upper(const char* source) { return _internal::transform(source, source + std::strlen(source), ::toupper); }
    inline std::string upper(char* source) { return upper(const_cast<const char*>(source)); }

    // inline std::string& capitalize(std::string& source)
    // {
    //     if (!source.empty()) {
    //         std::transform(source.begin(), source.begin() + 1, source.begin(), ::toupper);
    //         std::transform(source.begin() + 1, source.end(), source.begin() + 1, ::tolower);
    //     }
    //     return source;
    // }

    template <typename S> inline std::string capitalize(const S& source)
    {
        std::string result;
        if (!source.empty()) {
            std::transform(source.begin(), source.begin() + 1, std::back_inserter(result), ::toupper);
            std::transform(source.begin() + 1, source.end(), std::back_inserter(result), ::tolower);
        }
        return result;
    }

      // ----------------------------------------------------------------------
      // ends_with
      // ----------------------------------------------------------------------

    template <typename S> inline bool ends_with(const S& data, const char* end)
    {
        const std::string_view end_view{end};
        return std::string_view(data.data() + data.size() - end_view.size(), end_view.size()) == end_view;
    }

      // ----------------------------------------------------------------------
      // compare
      // ----------------------------------------------------------------------

    inline int compare(const char* a, size_t al, const char* b, size_t bl)
    {
        auto r = std::memcmp(a, b, std::min(al, bl));
        if (r == 0 && al != bl)
            return al < bl ? -1 : 1;
        else
            return r;
    }

    inline int compare(std::string a, std::string b) { return compare(a.c_str(), a.size(), b.c_str(), b.size()); }
    inline int compare(std::string a, const char* b) { return compare(a.c_str(), a.size(), b, std::strlen(b)); }
    inline int compare(const char* a, std::string b) { return compare(a, std::strlen(a), b.c_str(), b.size()); }

    inline int compare(std::initializer_list<std::string> as, std::initializer_list<std::string> bs)
    {
        assert(as.size() == bs.size());
        for (auto ap = as.begin(), bp = bs.begin(); ap != as.end(); ++ap, ++bp) {
            if (const auto r = compare(*ap, *bp); r != 0)
                return r;
        }
        return 0;
    }

      // ----------------------------------------------------------------------
      // join
      // ----------------------------------------------------------------------

    template <typename Iterator> inline std::string join(std::string separator, Iterator first, Iterator last)
    {
        std::string result;
        if (first != last) {
              // Note last - first below does not supported for std::set
              // const size_t resulting_size = std::accumulate(first, last, separator.size() * static_cast<size_t>(last - first - 1), [](size_t acc, const std::string& n) -> size_t { return acc + n.size(); });
              // result.reserve(resulting_size);
            for ( ; first != last; ++first) {
                const auto f_s = acmacs::to_string(*first);
                if (!f_s.empty()) {
                    if (!result.empty())
                        result.append(separator);
                    result.append(f_s);
                }
            }
        }
        return result;
    }

    template <typename Iterator, typename Converter> inline std::string join(std::string separator, Iterator first, Iterator last, Converter convert)
    {
        std::string result;
        for ( ; first != last; ++first) {
            const auto f_s = convert(*first);
            if (!f_s.empty()) {
                if (!result.empty())
                    result.append(separator);
                result.append(f_s);
            }
        }
        return result;
    }

    template <typename Collection> inline std::string join(std::string separator, const Collection& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::string separator, std::initializer_list<std::string>&& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::string separator, std::initializer_list<std::string_view>&& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::initializer_list<std::string>&& parts)
    {
        // std::vector<std::string> p{parts};
        // return join(" ", std::begin(p), std::remove(std::begin(p), std::end(p), std::string()));
        return join(" ", std::begin(parts), std::end(parts));
    }

    enum ShowBase { NotShowBase, ShowBase };
    enum OutputCase { Uppercase, Lowercase };

    template <typename T, typename = std::enable_if<std::is_integral<T>::value>> inline std::string to_hex_string(T aValue, enum ShowBase aShowBase, OutputCase aOutputCase = Uppercase)
    {
        std::ostringstream stream;
          // stream << (aShowBase == ShowBase ? std::showbase : std::noshowbase);
        if (aShowBase == ShowBase)
            stream << "0x";
        stream << std::setfill('0') << std::setw(sizeof(aValue)*2) << std::hex << std::noshowbase;
        stream << (aOutputCase == Uppercase ? std::uppercase : std::nouppercase);
        if constexpr (std::is_same_v<T, char> || std::is_same_v<T, unsigned char>) {
                stream << static_cast<unsigned>(aValue);
            }
        else {
            stream << aValue;
        }
        return stream.str();
    }

    template <typename T> inline std::string to_hex_string(const T* aPtr)
    {
        std::ostringstream stream;
        const void* value = reinterpret_cast<const void*>(aPtr);
        stream << value; // std::setfill('0') << std::setw(sizeof(value)*2) << std::hex << value;
        return stream.str();
    }

// ----------------------------------------------------------------------

    template <typename S> inline std::string_view string_view(const S& aSrc, size_t aOffset)
    {
        return std::string_view(aSrc.data() + aOffset, aSrc.size() - aOffset);
    }

// ----------------------------------------------------------------------

} // namespace string

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>minor fix<commit_after>#pragma once

#include <string>
#include <string_view>
#include <vector>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <iterator>
#include <utility>
#include <initializer_list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <functional>
#include <cassert>

#include "acmacs-base/to-string.hh"

// ----------------------------------------------------------------------

namespace string
{
      // ----------------------------------------------------------------------

    inline std::string first_letter_of_words(std::string s)
    {
        std::string result;
        bool add = true;
        for (char c: s) {
            if (c == ' ') {
                add = true;
            }
            else if (add) {
                result.push_back(c);
                add = false;
            }
        }
        return result;
    }

      // ----------------------------------------------------------------------

    namespace _internal {
        template <typename InputIterator, typename Source> inline std::pair<InputIterator, InputIterator> strip_begin_end(Source& source)
        {
            auto predicate = [](auto c) { return std::isspace(c); }; // have to use lambda, other compiler cannot infer Predicate type from isspace
            auto e = std::find_if_not(source.rbegin(), source.rend(), predicate);
            auto b = std::find_if_not(source.begin(), e.base(), predicate);
            return std::make_pair(b, e.base());
        }
    } // namespace _internal

    // inline std::string& strip(std::string& source)
    // {
    //     auto be = _internal::strip_begin_end<std::string::iterator>(source);
    //     source.erase(be.second, source.end()); // erase at the end first
    //     source.erase(source.begin(), be.first); // invalidates be.second!
    //     return source;
    // }

    // inline std::string strip(std::string&& source)
    // {
    //     auto be = _internal::strip_begin_end<std::string::iterator>(source);
    //     source.erase(be.second, source.end()); // erase at the end first
    //     source.erase(source.begin(), be.first); // invalidates be.second!
    //     return source;
    // }

    inline std::string strip(std::string source)
    {
        auto be = _internal::strip_begin_end<std::string::const_iterator>(source);
        return std::string(be.first, be.second);
    }

      // ----------------------------------------------------------------------

    inline std::string replace(std::string source, std::string look_for, std::string replace_with)
    {
        std::string result;
        std::string::size_type start = 0;
        while (true) {
            const auto pos = source.find(look_for, start);
            if (pos != std::string::npos) {
                result.append(source.begin() + static_cast<std::string::difference_type>(start), source.begin() + static_cast<std::string::difference_type>(pos));
                result.append(replace_with);
                start = pos + look_for.size();
            }
            else {
                result.append(source.begin() + static_cast<std::string::difference_type>(start), source.end());
                break;
            }
        }
        return result;
    }

      // ----------------------------------------------------------------------

    namespace _internal
    {
        template <typename Iter> inline std::string transform(Iter first, Iter last, std::function<char (char)> func)
        {
            std::string result;
            std::transform(first, last, std::back_inserter(result), func);
            return result;
        }
    }

    template <typename S> inline std::string lower(const S& source) { return _internal::transform(source.begin(), source.end(), ::tolower); }
    inline std::string lower(const char* source) { return _internal::transform(source, source + std::strlen(source), ::tolower); }
    inline std::string lower(char* source) { return lower(const_cast<const char*>(source)); }

    template <typename S> inline std::string upper(const S& source) { return _internal::transform(source.begin(), source.end(), ::toupper); }
    inline std::string upper(const char* source) { return _internal::transform(source, source + std::strlen(source), ::toupper); }
    inline std::string upper(char* source) { return upper(const_cast<const char*>(source)); }

    // inline std::string& capitalize(std::string& source)
    // {
    //     if (!source.empty()) {
    //         std::transform(source.begin(), source.begin() + 1, source.begin(), ::toupper);
    //         std::transform(source.begin() + 1, source.end(), source.begin() + 1, ::tolower);
    //     }
    //     return source;
    // }

    template <typename S> inline std::string capitalize(const S& source)
    {
        std::string result;
        if (!source.empty()) {
            std::transform(source.begin(), source.begin() + 1, std::back_inserter(result), ::toupper);
            std::transform(source.begin() + 1, source.end(), std::back_inserter(result), ::tolower);
        }
        return result;
    }

      // ----------------------------------------------------------------------
      // ends_with
      // ----------------------------------------------------------------------

    template <typename S> inline bool ends_with(const S& data, const char* end)
    {
        const std::string_view end_view{end};
        return std::string_view(data.data() + data.size() - end_view.size(), end_view.size()) == end_view;
    }

      // ----------------------------------------------------------------------
      // compare
      // ----------------------------------------------------------------------

    inline int compare(const char* a, size_t al, const char* b, size_t bl)
    {
        auto r = std::memcmp(a, b, std::min(al, bl));
        if (r == 0 && al != bl)
            return al < bl ? -1 : 1;
        else
            return r;
    }

    inline int compare(const std::string& a, const std::string& b) { return compare(a.c_str(), a.size(), b.c_str(), b.size()); }
    inline int compare(const std::string& a, const char* b) { return compare(a.c_str(), a.size(), b, std::strlen(b)); }
    inline int compare(const char* a, const std::string& b) { return compare(a, std::strlen(a), b.c_str(), b.size()); }

    inline int compare(std::initializer_list<std::string> as, std::initializer_list<std::string> bs)
    {
        assert(as.size() == bs.size());
        for (auto ap = as.begin(), bp = bs.begin(); ap != as.end(); ++ap, ++bp) {
            if (const auto r = compare(*ap, *bp); r != 0)
                return r;
        }
        return 0;
    }

      // ----------------------------------------------------------------------
      // join
      // ----------------------------------------------------------------------

    template <typename Iterator> inline std::string join(std::string separator, Iterator first, Iterator last)
    {
        std::string result;
        if (first != last) {
              // Note last - first below does not supported for std::set
              // const size_t resulting_size = std::accumulate(first, last, separator.size() * static_cast<size_t>(last - first - 1), [](size_t acc, const std::string& n) -> size_t { return acc + n.size(); });
              // result.reserve(resulting_size);
            for ( ; first != last; ++first) {
                const auto f_s = acmacs::to_string(*first);
                if (!f_s.empty()) {
                    if (!result.empty())
                        result.append(separator);
                    result.append(f_s);
                }
            }
        }
        return result;
    }

    template <typename Iterator, typename Converter> inline std::string join(std::string separator, Iterator first, Iterator last, Converter convert)
    {
        std::string result;
        for ( ; first != last; ++first) {
            const auto f_s = convert(*first);
            if (!f_s.empty()) {
                if (!result.empty())
                    result.append(separator);
                result.append(f_s);
            }
        }
        return result;
    }

    template <typename Collection> inline std::string join(std::string separator, const Collection& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::string separator, std::initializer_list<std::string>&& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::string separator, std::initializer_list<std::string_view>&& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::initializer_list<std::string>&& parts)
    {
        // std::vector<std::string> p{parts};
        // return join(" ", std::begin(p), std::remove(std::begin(p), std::end(p), std::string()));
        return join(" ", std::begin(parts), std::end(parts));
    }

    enum ShowBase { NotShowBase, ShowBase };
    enum OutputCase { Uppercase, Lowercase };

    template <typename T, typename = std::enable_if<std::is_integral<T>::value>> inline std::string to_hex_string(T aValue, enum ShowBase aShowBase, OutputCase aOutputCase = Uppercase)
    {
        std::ostringstream stream;
          // stream << (aShowBase == ShowBase ? std::showbase : std::noshowbase);
        if (aShowBase == ShowBase)
            stream << "0x";
        stream << std::setfill('0') << std::setw(sizeof(aValue)*2) << std::hex << std::noshowbase;
        stream << (aOutputCase == Uppercase ? std::uppercase : std::nouppercase);
        if constexpr (std::is_same_v<T, char> || std::is_same_v<T, unsigned char>) {
                stream << static_cast<unsigned>(aValue);
            }
        else {
            stream << aValue;
        }
        return stream.str();
    }

    template <typename T> inline std::string to_hex_string(const T* aPtr)
    {
        std::ostringstream stream;
        const void* value = reinterpret_cast<const void*>(aPtr);
        stream << value; // std::setfill('0') << std::setw(sizeof(value)*2) << std::hex << value;
        return stream.str();
    }

// ----------------------------------------------------------------------

    template <typename S> inline std::string_view string_view(const S& aSrc, size_t aOffset)
    {
        return std::string_view(aSrc.data() + aOffset, aSrc.size() - aOffset);
    }

// ----------------------------------------------------------------------

} // namespace string

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#pragma once

#include <iostream>
#include <iomanip>
#include <string>
#include <chrono>

// ----------------------------------------------------------------------

enum class report_time { No, Yes };

class Timeit
{
 public:
    inline Timeit(std::string msg, report_time aReport = report_time::Yes, std::ostream& out = std::cerr)
        : message(msg), out_stream(out), mReport(aReport), start(std::chrono::steady_clock::now()) {}

    inline ~Timeit() { report(); }

    inline void report()
        {
            if (mReport == report_time::Yes) {
                const auto total = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
                const decltype(total) s = total / 1000;
                const decltype(total) ms = total % 1000;
                out_stream << message;
                out_stream << s << '.' << std::setw(3) << std::setfill('0') << ms << std::setw(0) << '\n';
                mReport = report_time::No;
            }
        }

    inline void message_append(std::string to_append) { message += to_append; }

 private:
    std::string message;
    std::ostream& out_stream;
    report_time mReport;
    decltype(std::chrono::steady_clock::now()) start;
};

inline report_time do_report_time(bool do_report) { return do_report ? report_time::Yes : report_time::No; }

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>minor fix<commit_after>#pragma once

#include <iostream>
#include <iomanip>
#include <string>
#include <chrono>

// ----------------------------------------------------------------------

enum class report_time { No, Yes };

class Timeit
{
 public:
    inline Timeit(std::string msg, report_time aReport = report_time::Yes, std::ostream& out = std::cerr)
        : message(msg), out_stream(out), mReport(aReport), start(std::chrono::steady_clock::now()) {}

    inline ~Timeit() { report(); }

    inline void report()
        {
            if (mReport == report_time::Yes) {
                const auto total = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
                const decltype(total) s = total / 1000;
                const decltype(total) ms = total % 1000;
                out_stream << message;
                out_stream << s << '.' << std::setw(3) << std::setfill('0') << ms << std::setw(0) << '\n';
                mReport = report_time::No;
            }
        }

    inline void message_append(std::string to_append) { message += to_append; }

 private:
    std::string message;
    std::ostream& out_stream;
    report_time mReport;
    decltype(std::chrono::steady_clock::now()) start;
};

inline report_time do_report_time(bool do_report) { return do_report ? report_time::Yes : report_time::No; }

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#include "Supernova.h"

void init(){

}
<commit_msg>Added namespace to default project<commit_after>#include "Supernova.h"

using namespace Supernova;

void init() {

}<|endoftext|>


<commit_before>#include "stdafx.h"
#include "MyUtil.h"

#include "DebugNew.h"

namespace MyUtils
{
	template<typename T> void LoadBinaryFromFileImpl(LPCWSTR pFilePath, std::vector<T>& outBuffer)
	{
		//static_assert((sizeof(T) == 1), "Unsupported size!!");

		// 炩߃NAĂB
		outBuffer.clear();

		// t@C TCY̎擾ɂ Windows API  GetFileSizeEx()  FindFirstFile() g@邪A OS ւ̈ڐAɗ̂ŎgȂB
		// fseek(), ftell() ͘_OB
		// https://www.jpcert.or.jp/sc-rules/c-fio19-c.html
		// POSIX x[X stat gƂɂB
		// _stat32(), _wstat32(), _stat32i64(), _wstat32i64() ̓^CX^v 2038-01-18 23:59:59 ܂łȂ̂Ř_OB
		// _stat64i32(), _wstat64i32()  0x7FFFFFFF [bytes] (2GB - 1B) ܂ł̃t@CɈȂB
		// 2GB ȏ̃t@CɈ悤ɂɂ _stat64(), _wstat64() gKvB

#if defined(_M_X64) || defined(_M_ARM64)
		// 64bit rh̔ _WIN64 ł悳B
		// https://msdn.microsoft.com/en-us/library/b0084kay.aspx
		// Ȃ݂ x86  ARM ł _WIN64 ͒`ȂAx64  ARM64 ł _WIN64  _WIN32 ̗`̂ŒӁB
#elif defined(_M_IX86) || defined(_M_ARM)
#else
#error Not supported platform!!
#endif
		// \̂Ɠ̊֐݂̂ŁAC++ ł struct ŏCKvB
		struct _stat64 fileStats = {};
		const auto getFileStatFunc = _wstat64;

		// t@C TCY擾łȂA̓TCYꍇ̓G[B
		if (getFileStatFunc(pFilePath, &fileStats) != 0 || fileStats.st_size < 0)
		{
			throw std::exception("Cannot get the file stats for the file!!");
		}

		if (fileStats.st_size % sizeof(T) != 0)
		{
			throw std::exception("The file size is not a multiple of the expected size of element!!");
		}

		const auto fileSizeInBytes = static_cast<uint64_t>(fileStats.st_size);

		// MFC  GDI+ gꍇ NOMINMAX `łAזƂ׈ min/max }N𖳌łȂB
		// Windows SDK  <intsafe.h> Œ`Ă SIZE_T_MAX ȂǂւƂĎg@邪A
		// R[hxł̈ڐA߂邽߂ɁAZgă}NWJB
		// http://d.hatena.ne.jp/yohhoy/20120115/p1

		// size_t ŕ\łȂꍇ̓G[B
		if (sizeof(size_t) < 8 && (std::numeric_limits<size_t>::max)() < fileSizeInBytes)
		{
			throw std::exception("The file size is over the capacity on this platform!!");
		}

		if (fileStats.st_size == 0)
		{
			return;
		}

		const auto numElementsInFile = static_cast<size_t>(fileStats.st_size / sizeof(T));

		outBuffer.resize(numElementsInFile);

#if 0
		// std::fstream ̏ꍇAMSVC ̃fobO rhł́A MB ̃t@CǂݍނƂ20bȏ̎ԂB
		// ] CRT t@Co͊֐ɂ́AfobO rhłĂ܂ł̒vIȃI[o[wbh͂ȂB
		std::basic_ifstream<T> ifs(pFilePath, std::ios::in | std::ios::binary);

		if (ifs.fail())
		{
			throw std::exception("Cannot open the file!!");
		}

		ifs.seekg(0, std::fstream::end);
		const auto endPos = ifs.tellg();
		ifs.clear();
		ifs.seekg(0, std::fstream::beg);
		const auto begPos = ifs.tellg();
		const auto fileSize = endPos - begPos; // std::streamoff ^BVC2012 ł 32bit łł long long ɂȂ炵B
		static_assert(sizeof(fileSize) >= 8, "Size of pos_type must be greater than or equal to 8 bytes!!");
		static_assert(sizeof(fpos_t) >= 8, "Size of fpos_t must be greater than or equal to 8 bytes!!");

		ifs.read(&outBuffer[0], numElementsInFile);
#else
		FILE* pFile = nullptr;
		const auto retCode = _wfopen_s(&pFile, pFilePath, L"rb");
		if (retCode != 0 || pFile == nullptr)
		{
			throw std::exception("Cannot open the file!!");
		}
		fread_s(&outBuffer[0], numElementsInFile * sizeof(T), sizeof(T), numElementsInFile, pFile);
		fclose(pFile);
		pFile = nullptr;
#endif
	}

	template<typename T> bool LoadBinaryFromFileImpl2(LPCWSTR pFilePath, std::vector<T>& outBuffer)
	{
		try
		{
			LoadBinaryFromFileImpl(pFilePath, outBuffer);
			return true;
		}
		catch (const std::exception& ex)
		{
			const CStringW strMsg(ex.what());
			ATLTRACE(L"%s <%s>\n", strMsg.GetString(), pFilePath);
			return false;
		}
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<char>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<int8_t>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<uint8_t>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<int32_t>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<uint32_t>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<float>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	// Rs[RXgN^ C++11 [u RXgN^D悳邱ƂlAĈł͂Ȃ߂lŕԂB
	// std::move() Ȃł悢Bނ돑 RVO (Return Value Optimization) jQ邱Ƃ炵H
	// HACK: std::vector ƃ|C^͈ړȂAstd::string ƃ|C^ړĂ܂HiĊ蓖ĂĂ܂Hj
	std::vector<char> ConvertUtf16toUtf8(const wchar_t* srcText)
	{
		_ASSERTE(srcText != nullptr);
		const int textLen = static_cast<int>(wcslen(srcText));
		if (textLen <= 0)
		{
			return{ 0 };
		}
		const int reqSize = ::WideCharToMultiByte(CP_UTF8, 0, srcText, textLen, nullptr, 0, nullptr, nullptr);
		if (reqSize > 0)
		{
			std::vector<char> buff(reqSize + 1); // Ō + 1 ͕K{炵BI[ null ܂܂ȂTCYԂ炵B
			//std::vector<char> buff(reqSize);
			::WideCharToMultiByte(CP_UTF8, 0, srcText, textLen, &buff[0], reqSize, nullptr, nullptr);
			return buff;
		}
		else
		{
			// SɃG[Ȃ̂Ŗ{͗O𓊂ׂH
			//return std::vector<char>();
			return{ 0 };
		}
	}

	std::vector<wchar_t> ConvertUtf8toUtf16(const char* srcText)
	{
		_ASSERTE(srcText != nullptr);
		const int textLen = static_cast<int>(strlen(srcText));
		if (textLen <= 0)
		{
			return{ 0 };
		}
		const int reqSize = ::MultiByteToWideChar(CP_UTF8, 0, srcText, textLen, nullptr, 0);
		if (reqSize > 0)
		{
			std::vector<wchar_t> buff(reqSize + 1); // Ō + 1 ͕K{炵BI[ null ܂܂ȂTCYԂ炵B
			//std::vector<wchar_t> buff(reqSize);
			::MultiByteToWideChar(CP_UTF8, 0, srcText, textLen, &buff[0], reqSize);
			return buff;
		}
		else
		{
			// SɃG[Ȃ̂Ŗ{͗O𓊂ׂH
			//return std::vector<wchar_t>();
			return{ 0 };
		}
	}

	bool GetUtf8FullPath(const wchar_t* inRelFilePath, std::string& outFullPath)
	{
		const int RequiredStringBufferSize = 1024;
		wchar_t inFullPath[RequiredStringBufferSize] = {};
		char outFullPathBuf[RequiredStringBufferSize] = {};

		if (_wfullpath(inFullPath, inRelFilePath, RequiredStringBufferSize) == nullptr)
		{
			return false;
		}

		if (::WideCharToMultiByte(CP_UTF8, 0, inFullPath, -1, outFullPathBuf, RequiredStringBufferSize, nullptr, nullptr) == 0)
		{
			return false;
		}

		outFullPath = outFullPathBuf;
		return true;
	}

} // end of namespace
<commit_msg>Appended comments.<commit_after>#include "stdafx.h"
#include "MyUtil.h"

#include "DebugNew.h"

namespace MyUtils
{
	template<typename T> void LoadBinaryFromFileImpl(LPCWSTR pFilePath, std::vector<T>& outBuffer)
	{
		//static_assert((sizeof(T) == 1), "Unsupported size!!");

		// 炩߃NAĂB
		outBuffer.clear();

		// t@C TCY̎擾ɂ Windows API  GetFileSizeEx()  FindFirstFile() g@邪A OS ւ̈ڐAɗ̂ŎgȂB
		// fseek(), ftell() ͘_OB
		// https://www.jpcert.or.jp/sc-rules/c-fio19-c.html
		// POSIX x[X stat gƂɂB
		// _stat32(), _wstat32(), _stat32i64(), _wstat32i64() ̓^CX^v 2038-01-18 23:59:59 ܂łȂ̂Ř_OB
		// _stat64i32(), _wstat64i32()  0x7FFFFFFF [bytes] (2GB - 1B) ܂ł̃t@CɈȂB
		// 2GB ȏ̃t@CɈ悤ɂɂ _stat64(), _wstat64() gKvB

#if defined(_M_X64) || defined(_M_ARM64)
		// 64bit rh̔ _WIN64 ł悳B
		// https://msdn.microsoft.com/en-us/library/b0084kay.aspx
		// Ȃ݂ x86  ARM ł _WIN64 ͒`ȂAx64  ARM64 ł _WIN64  _WIN32 ̗`̂ŒӁB
#elif defined(_M_IX86) || defined(_M_ARM)
#else
#error Not supported platform!!
#endif
		// \̂Ɠ̊֐݂̂ŁAC++ ł struct ŏCKvB
		struct _stat64 fileStats = {};
		const auto getFileStatFunc = _wstat64;

		// t@C TCY擾łȂA̓TCYꍇ̓G[B
		if (getFileStatFunc(pFilePath, &fileStats) != 0 || fileStats.st_size < 0)
		{
			throw std::exception("Cannot get the file stats for the file!!");
		}

		if (fileStats.st_size % sizeof(T) != 0)
		{
			throw std::exception("The file size is not a multiple of the expected size of element!!");
		}

		const auto fileSizeInBytes = static_cast<uint64_t>(fileStats.st_size);

		// MFC  GDI+ gꍇ NOMINMAX `łAזƂ׈ min/max }N𖳌łȂB
		// Windows SDK  <intsafe.h> Œ`Ă SIZE_T_MAX ȂǂւƂĎg@邪A
		// R[hxł̈ڐA߂邽߂ɁAZgă}NWJB
		// http://d.hatena.ne.jp/yohhoy/20120115/p1

		// size_t ŕ\łȂꍇ̓G[B
		if (sizeof(size_t) < 8 && (std::numeric_limits<size_t>::max)() < fileSizeInBytes)
		{
			throw std::exception("The file size is over the capacity on this platform!!");
		}

		if (fileStats.st_size == 0)
		{
			return;
		}

		const auto numElementsInFile = static_cast<size_t>(fileStats.st_size / sizeof(T));

		outBuffer.resize(numElementsInFile);

#if 0
		// std::fstream ̏ꍇAMSVC ̃fobO rhł́A MB ̃t@CǂݍނƂ20bȏ̎ԂB
		// ] CRT t@Co͊֐ɂ́AfobO rhłĂ܂ł̒vIȃI[o[wbh͂ȂB
		std::basic_ifstream<T> ifs(pFilePath, std::ios::in | std::ios::binary);

		if (ifs.fail())
		{
			throw std::exception("Cannot open the file!!");
		}

		ifs.seekg(0, std::fstream::end);
		const auto endPos = ifs.tellg();
		ifs.clear();
		ifs.seekg(0, std::fstream::beg);
		const auto begPos = ifs.tellg();
		const auto fileSize = endPos - begPos; // std::streamoff ^BVC2012 ł 32bit łł long long ɂȂ炵B
		static_assert(sizeof(fileSize) >= 8, "Size of pos_type must be greater than or equal to 8 bytes!!");
		static_assert(sizeof(fpos_t) >= 8, "Size of fpos_t must be greater than or equal to 8 bytes!!");

		ifs.read(&outBuffer[0], numElementsInFile);
#else
		FILE* pFile = nullptr;
		const auto retCode = _wfopen_s(&pFile, pFilePath, L"rb");
		if (retCode != 0 || pFile == nullptr)
		{
			throw std::exception("Cannot open the file!!");
		}
		fread_s(&outBuffer[0], numElementsInFile * sizeof(T), sizeof(T), numElementsInFile, pFile);
		fclose(pFile);
		pFile = nullptr;
#endif
	}

	template<typename T> bool LoadBinaryFromFileImpl2(LPCWSTR pFilePath, std::vector<T>& outBuffer)
	{
		try
		{
			LoadBinaryFromFileImpl(pFilePath, outBuffer);
			return true;
		}
		catch (const std::exception& ex)
		{
			const CStringW strMsg(ex.what());
			ATLTRACE(L"%s <%s>\n", strMsg.GetString(), pFilePath);
			return false;
		}
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<char>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<int8_t>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<uint8_t>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<int32_t>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<uint32_t>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	bool LoadBinaryFromFile(LPCWSTR pFilePath, std::vector<float>& outBuffer)
	{
		return LoadBinaryFromFileImpl2(pFilePath, outBuffer);
	}

	//  vector ɑ΂ vector.data()  nullptr ԂƂɒӁB
	// Rs[RXgN^ C++11 [u RXgN^D悳邱ƂlAĈł͂Ȃ߂lŕԂB
	// std::move() Ȃł悢Bނ돑 RVO (Return Value Optimization) jQ邱Ƃ炵H
	// std::vector ̃[uƃ|C^̂ւŝŁAʓIɃ[uƃ[uƂŃ|C^̒l͕ςȂB
	// Astd::string ƕK|C^̂ւɂ͂ȂȂ͗lB
	// [usہA[u̕obt@eʂ\ȏꍇ́Amemmove() ɂ郁ubÑRs[ƂȂ͗lB
	// [u̕obt@eʂs\ȏꍇ́A|C^̂ւɂȂ͗lB
	// VC2015 Update3 łAgcc 6.3 łl̎ɂȂĂ炵B
	// ɂAq[v̍Ċ蓖Ă͔Ȃ͗lB
	// ȂAC++11 Œǉꂽ codecvt ́AC++17 Ŕ񐄏ƂȂĂ܂B
	std::vector<char> ConvertUtf16toUtf8(const wchar_t* srcText)
	{
		_ASSERTE(srcText != nullptr);
		const int textLen = static_cast<int>(wcslen(srcText));
		if (textLen <= 0)
		{
			return{ 0 };
		}
		const int reqSize = ::WideCharToMultiByte(CP_UTF8, 0, srcText, textLen, nullptr, 0, nullptr, nullptr);
		if (reqSize > 0)
		{
			std::vector<char> buff(reqSize + 1); // Ō + 1 ͕K{炵BI[ null ܂܂ȂTCYԂ炵B
			//std::vector<char> buff(reqSize);
			::WideCharToMultiByte(CP_UTF8, 0, srcText, textLen, &buff[0], reqSize, nullptr, nullptr);
			return buff;
		}
		else
		{
			// SɃG[Ȃ̂Ŗ{͗O𓊂ׂH
			//return std::vector<char>();
			return{ 0 };
		}
	}

	std::vector<wchar_t> ConvertUtf8toUtf16(const char* srcText)
	{
		_ASSERTE(srcText != nullptr);
		const int textLen = static_cast<int>(strlen(srcText));
		if (textLen <= 0)
		{
			return{ 0 };
		}
		const int reqSize = ::MultiByteToWideChar(CP_UTF8, 0, srcText, textLen, nullptr, 0);
		if (reqSize > 0)
		{
			std::vector<wchar_t> buff(reqSize + 1); // Ō + 1 ͕K{炵BI[ null ܂܂ȂTCYԂ炵B
			//std::vector<wchar_t> buff(reqSize);
			::MultiByteToWideChar(CP_UTF8, 0, srcText, textLen, &buff[0], reqSize);
			return buff;
		}
		else
		{
			// SɃG[Ȃ̂Ŗ{͗O𓊂ׂH
			//return std::vector<wchar_t>();
			return{ 0 };
		}
	}

	bool GetUtf8FullPath(const wchar_t* inRelFilePath, std::string& outFullPath)
	{
		const int RequiredStringBufferSize = 1024;
		wchar_t inFullPath[RequiredStringBufferSize] = {};
		char outFullPathBuf[RequiredStringBufferSize] = {};

		if (_wfullpath(inFullPath, inRelFilePath, RequiredStringBufferSize) == nullptr)
		{
			return false;
		}

		if (::WideCharToMultiByte(CP_UTF8, 0, inFullPath, -1, outFullPathBuf, RequiredStringBufferSize, nullptr, nullptr) == 0)
		{
			return false;
		}

		outFullPath = outFullPathBuf;
		return true;
	}

} // end of namespace
<|endoftext|>