<commit_before>/* Copyright (c) 2009, Avian Contributors

   Permission to use, copy, modify, and/or distribute this software
   for any purpose with or without fee is hereby granted, provided
   that the above copyright notice and this permission notice appear
   in all copies.

   There is NO WARRANTY for this software.  See license.txt for
   details. */

#include "machine.h"
#include "constants.h"
#include "processor.h"

using namespace vm;

namespace {

void
setProperty(Thread* t, object method, object properties,
            const char* name, const void* value, const char* format = "%s")
{
  PROTECT(t, method);
  PROTECT(t, properties);

  object n = makeString(t, "%s", name);
  PROTECT(t, n);

  object v = makeString(t, format, value);

  t->m->processor->invoke(t, method, properties, n, v);
}

} // namespace

namespace vm {

jobject JNICALL
NewDirectByteBuffer(Thread* t, void* address, jlong capacity)
{
  const char* pointerClassName;
  const char* initSpec;
  if (BytesPerWord == 8) {
    pointerClassName = "gnu/classpath/Pointer64";
    initSpec = "(J)V";
  } else {
    pointerClassName = "gnu/classpath/Pointer32";
    initSpec = "(I)V";
  }

  object pointerClass = resolveClass(t, pointerClassName);
  if (UNLIKELY(pointerClass == 0)) return 0;
  PROTECT(t, pointerClass);

  object pointerConstructor = resolveMethod
    (t, pointerClass, "<init>", initSpec);
  if (UNLIKELY(pointerConstructor == 0)) return 0;

  object pointer = make(t, pointerClass);
  PROTECT(t, pointer);

  t->m->processor->invoke(t, pointerConstructor, pointer, address);
  if (UNLIKELY(t->exception)) return 0;

  object bufferClass = resolveClass
    (t, "java/nio/DirectByteBufferImpl$ReadWrite");
  if (UNLIKELY(bufferClass == 0)) return 0;
  PROTECT(t, bufferClass);

  object bufferConstructor = resolveMethod
    (t, bufferClass, "<init>", "(Lgnu/classpath/Pointer;int)V");
  if (UNLIKELY(bufferConstructor == 0)) return 0;

  object buffer = make(t, bufferClass);
  PROTECT(t, buffer);

  t->m->processor->invoke
    (t, bufferConstructor, buffer, &pointer, static_cast<jint>(capacity));
  if (UNLIKELY(t->exception)) return 0;

  return makeLocalReference(t, buffer);
}

void* JNICALL
GetDirectBufferAddress(Thread* t, jobject buffer)
{
  object addressField = resolveField
    (t, objectClass(t, *buffer), "address", "Lgnu/classpath/Pointer;");
  if (UNLIKELY(addressField == 0)) return 0;

  object address = cast<object>(*buffer, fieldOffset(t, addressField));
  if (address == 0) return 0;

  const char* dataSpec;
  if (BytesPerWord == 8) {
    dataSpec = "J";
  } else {
    dataSpec = "I";
  }

  object dataField = resolveField
    (t, objectClass(t, address), "data", dataSpec);
  if (UNLIKELY(dataField == 0)) return 0;

  return cast<void*>(address, fieldOffset(t, dataField));
}

jlong JNICALL
GetDirectBufferCapacity(Thread* t, jobject buffer)
{
  object capField = resolveField(t, objectClass(t, *buffer), "cap", "I");
  if (UNLIKELY(capField == 0)) return 0;

  return cast<jint>(*buffer, fieldOffset(t, capField));
}

} // namespace vm

extern "C" JNIEXPORT void JNICALL
Avian_gnu_classpath_VMSystemProperties_preInit
(Thread* t, object, uintptr_t* arguments)
{
  object properties = reinterpret_cast<object>(arguments[0]);
  PROTECT(t, properties);

  object method = resolveMethod
    (t, "java/util/Properties", "setProperty",
     "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");

  if (UNLIKELY(t->exception)) {
    return;
  }

  PROTECT(t, method);

  setProperty(t, method, properties, "java.vm.name", "Avian");

  setProperty(t, method, properties, "java.protocol.handler.pkgs", "avian");

  setProperty(t, method, properties, "file.encoding", "ASCII");

  // specify a bogus library path so we can do our own search in
  // VMRuntime.nativeLoad:
#define LIBRARY_PATH_SENTINAL "*"
  setProperty(t, method, properties, "java.library.path",
              LIBRARY_PATH_SENTINAL);

#ifdef WIN32
#  define FILE_SEPARATOR "\\"

  setProperty(t, method, properties, "line.separator", "\r\n");
  setProperty(t, method, properties, "file.separator", FILE_SEPARATOR);
  setProperty(t, method, properties, "path.separator", ";");
  setProperty(t, method, properties, "os.name", "Windows");

  TCHAR buffer[MAX_PATH];
  GetTempPath(MAX_PATH, buffer);
  setProperty(t, method, properties, "java.io.tmpdir", buffer);

  setProperty(t, method, properties, "user.home",
              _wgetenv(L"USERPROFILE"), "%ls");

  GetCurrentDirectory(MAX_PATH, buffer);
  setProperty(t, method, properties, "user.dir", buffer);
#else
#  define FILE_SEPARATOR "/"

  setProperty(t, method, properties, "line.separator", "\n");
  setProperty(t, method, properties, "file.separator", FILE_SEPARATOR);
  setProperty(t, method, properties, "path.separator", ":");
#  ifdef __APPLE__
  setProperty(t, method, properties, "os.name", "Mac OS X");
#  else
  setProperty(t, method, properties, "os.name", "Linux");
#  endif
  setProperty(t, method, properties, "java.io.tmpdir", "/tmp");
  setProperty(t, method, properties, "user.home", getenv("HOME"));
  setProperty(t, method, properties, "user.dir", getenv("PWD"));
#endif
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_gnu_classpath_VMStackWalker_getClassContext
(Thread* t, object, uintptr_t*)
{
  class Visitor: public Processor::StackVisitor {
   public:
    Visitor(Thread* t):
      t(t), skipCount(1), trace(0), index(0), protector(t, &trace)
    { }

    virtual bool visit(Processor::StackWalker* walker) {
      if (skipCount == 0) {
        if (trace == 0) {
          trace = makeObjectArray
            (t, arrayBody(t, t->m->types, Machine::ClassType),
             walker->count());
        }

        assert(t, index < objectArrayLength(t, trace));

        set(t, trace, ArrayBody + (index * BytesPerWord),
            methodClass(t, walker->method()));

        ++ index;
        return true;
      } else {
        -- skipCount;
        return true;
      }
    }

    Thread* t;
    unsigned skipCount;
    object trace;
    unsigned index;
    Thread::SingleProtector protector;
  } v(t);

  t->m->processor->walkStack(t, &v);

  if (v.trace == 0) {
    v.trace = makeObjectArray
      (t, arrayBody(t, t->m->types, Machine::ClassType), 0);
  }

  return reinterpret_cast<int64_t>(v.trace);
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_gnu_classpath_VMStackWalker_getClassLoader
(Thread* t, object, uintptr_t* arguments)
{
  return reinterpret_cast<int64_t>
    (classLoader(t, reinterpret_cast<object>(arguments[0])));
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMRuntime_mapLibraryName
(Thread* t, object, uintptr_t* arguments)
{
  object name = reinterpret_cast<object>(arguments[0]);
  PROTECT(t, name);

  const unsigned soPrefixLength = sizeof(SO_PREFIX) - 1;
  const unsigned nameLength = stringLength(t, name);
  const unsigned soSuffixLength = sizeof(SO_SUFFIX) - 1;
  const unsigned total = soPrefixLength + nameLength + soSuffixLength;

  object s = makeByteArray(t, total + 1);
  char* p = reinterpret_cast<char*>(&byteArrayBody(t, s, 0));

  memcpy(p, SO_PREFIX, soPrefixLength);
  stringChars(t, name, p + soPrefixLength);
  memcpy(p + soPrefixLength + nameLength, SO_SUFFIX, soSuffixLength);
  p[total] = 0;

  return reinterpret_cast<int64_t>(makeString(t, s, 0, total, 0));
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_System_arraycopy
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMSystem_arraycopy
(Thread* t, object, uintptr_t* arguments)
{
  Avian_java_lang_System_arraycopy(t, 0, arguments);
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_load
(Thread* t, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMRuntime_nativeLoad
(Thread* t, object, uintptr_t* arguments)
{
  object name = reinterpret_cast<object>(arguments[0]);

  // given that we set java.library.path to LIBRARY_PATH_SENTINAL, we
  // can determine which names are filenames and which are library
  // names by looking for the prefix LIBRARY_PATH_SENTINAL
  // FILE_SEPARATOR

  unsigned length = stringLength(t, name);
  char n[length + 1];
  stringChars(t, name, n);

  const unsigned pathPrefixLength
    = sizeof(LIBRARY_PATH_SENTINAL) - 1
    + sizeof(FILE_SEPARATOR) - 1;

  bool mapName = (strncmp(n, LIBRARY_PATH_SENTINAL FILE_SEPARATOR,
                          pathPrefixLength) == 0);
  if (mapName) {
    // strip the path prefix, SO prefix, and SO suffix before passing
    // the name to Runtime.load

    const unsigned soPrefixLength = sizeof(SO_PREFIX) - 1;
    const unsigned soSuffixLength = sizeof(SO_SUFFIX) - 1;
    const unsigned newOffset
      = stringOffset(t, name) + pathPrefixLength + soPrefixLength;
    const unsigned newLength
      = length - pathPrefixLength - soPrefixLength - soSuffixLength;

    name = makeString(t, stringData(t, name), newOffset, newLength, 0);
  }

  uintptr_t args[] = { reinterpret_cast<uintptr_t>(name), mapName };

  Avian_java_lang_Runtime_load(t, 0, args);

  if (t->exception) {
    t->exception = 0;
    return 0;
  } else {
    return 1;
  }
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_primitiveClass
(Thread* t, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_getPrimitiveClass
(Thread* t, object, uintptr_t* arguments)
{
  return Avian_java_lang_Class_primitiveClass(t, 0, arguments);
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_System_identityHashCode
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMSystem_identityHashCode
(Thread* t, object, uintptr_t* arguments)
{
  return Avian_java_lang_System_identityHashCode(t, 0, arguments);
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_gc
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMRuntime_gc
(Thread* t, object, uintptr_t*)
{
  Avian_java_lang_Runtime_gc(t, 0, 0);
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMRuntime_runFinalizationForExit
(Thread*, object, uintptr_t*)
{
  // ignore
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMRuntime_exit
(Thread*, object, uintptr_t* arguments)
{
  exit(arguments[0]);
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findClass
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_loadClass
(Thread* t, object, uintptr_t* arguments)
{
  uintptr_t args[] = { 0, arguments[0] };

  return Avian_avian_SystemClassLoader_findClass(t, 0, args);
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findLoadedClass
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_findLoadedClass
(Thread* t, object, uintptr_t* arguments)
{
  uintptr_t args[] = { 0, arguments[1] };

  return Avian_avian_SystemClassLoader_findLoadedClass(t, 0, args);
}
<commit_msg>set os.arch property in Avian_gnu_classpath_VMSystemProperties_preInit<commit_after>/* Copyright (c) 2009, Avian Contributors

   Permission to use, copy, modify, and/or distribute this software
   for any purpose with or without fee is hereby granted, provided
   that the above copyright notice and this permission notice appear
   in all copies.

   There is NO WARRANTY for this software.  See license.txt for
   details. */

#include "machine.h"
#include "constants.h"
#include "processor.h"

using namespace vm;

namespace {

void
setProperty(Thread* t, object method, object properties,
            const char* name, const void* value, const char* format = "%s")
{
  PROTECT(t, method);
  PROTECT(t, properties);

  object n = makeString(t, "%s", name);
  PROTECT(t, n);

  object v = makeString(t, format, value);

  t->m->processor->invoke(t, method, properties, n, v);
}

} // namespace

namespace vm {

jobject JNICALL
NewDirectByteBuffer(Thread* t, void* address, jlong capacity)
{
  const char* pointerClassName;
  const char* initSpec;
  if (BytesPerWord == 8) {
    pointerClassName = "gnu/classpath/Pointer64";
    initSpec = "(J)V";
  } else {
    pointerClassName = "gnu/classpath/Pointer32";
    initSpec = "(I)V";
  }

  object pointerClass = resolveClass(t, pointerClassName);
  if (UNLIKELY(pointerClass == 0)) return 0;
  PROTECT(t, pointerClass);

  object pointerConstructor = resolveMethod
    (t, pointerClass, "<init>", initSpec);
  if (UNLIKELY(pointerConstructor == 0)) return 0;

  object pointer = make(t, pointerClass);
  PROTECT(t, pointer);

  t->m->processor->invoke(t, pointerConstructor, pointer, address);
  if (UNLIKELY(t->exception)) return 0;

  object bufferClass = resolveClass
    (t, "java/nio/DirectByteBufferImpl$ReadWrite");
  if (UNLIKELY(bufferClass == 0)) return 0;
  PROTECT(t, bufferClass);

  object bufferConstructor = resolveMethod
    (t, bufferClass, "<init>", "(Lgnu/classpath/Pointer;int)V");
  if (UNLIKELY(bufferConstructor == 0)) return 0;

  object buffer = make(t, bufferClass);
  PROTECT(t, buffer);

  t->m->processor->invoke
    (t, bufferConstructor, buffer, &pointer, static_cast<jint>(capacity));
  if (UNLIKELY(t->exception)) return 0;

  return makeLocalReference(t, buffer);
}

void* JNICALL
GetDirectBufferAddress(Thread* t, jobject buffer)
{
  object addressField = resolveField
    (t, objectClass(t, *buffer), "address", "Lgnu/classpath/Pointer;");
  if (UNLIKELY(addressField == 0)) return 0;

  object address = cast<object>(*buffer, fieldOffset(t, addressField));
  if (address == 0) return 0;

  const char* dataSpec;
  if (BytesPerWord == 8) {
    dataSpec = "J";
  } else {
    dataSpec = "I";
  }

  object dataField = resolveField
    (t, objectClass(t, address), "data", dataSpec);
  if (UNLIKELY(dataField == 0)) return 0;

  return cast<void*>(address, fieldOffset(t, dataField));
}

jlong JNICALL
GetDirectBufferCapacity(Thread* t, jobject buffer)
{
  object capField = resolveField(t, objectClass(t, *buffer), "cap", "I");
  if (UNLIKELY(capField == 0)) return 0;

  return cast<jint>(*buffer, fieldOffset(t, capField));
}

} // namespace vm

extern "C" JNIEXPORT void JNICALL
Avian_gnu_classpath_VMSystemProperties_preInit
(Thread* t, object, uintptr_t* arguments)
{
  object properties = reinterpret_cast<object>(arguments[0]);
  PROTECT(t, properties);

  object method = resolveMethod
    (t, "java/util/Properties", "setProperty",
     "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");

  if (UNLIKELY(t->exception)) {
    return;
  }

  PROTECT(t, method);

  setProperty(t, method, properties, "java.vm.name", "Avian");

  setProperty(t, method, properties, "java.protocol.handler.pkgs", "avian");

  setProperty(t, method, properties, "file.encoding", "ASCII");

  // specify a bogus library path so we can do our own search in
  // VMRuntime.nativeLoad:
#define LIBRARY_PATH_SENTINAL "*"
  setProperty(t, method, properties, "java.library.path",
              LIBRARY_PATH_SENTINAL);

#ifdef WIN32
#  define FILE_SEPARATOR "\\"

  setProperty(t, method, properties, "line.separator", "\r\n");
  setProperty(t, method, properties, "file.separator", FILE_SEPARATOR);
  setProperty(t, method, properties, "path.separator", ";");
  setProperty(t, method, properties, "os.name", "Windows");

  TCHAR buffer[MAX_PATH];
  GetTempPath(MAX_PATH, buffer);
  setProperty(t, method, properties, "java.io.tmpdir", buffer);

  setProperty(t, method, properties, "user.home",
              _wgetenv(L"USERPROFILE"), "%ls");

  GetCurrentDirectory(MAX_PATH, buffer);
  setProperty(t, method, properties, "user.dir", buffer);
#else
#  define FILE_SEPARATOR "/"

  setProperty(t, method, properties, "line.separator", "\n");
  setProperty(t, method, properties, "file.separator", FILE_SEPARATOR);
  setProperty(t, method, properties, "path.separator", ":");
#  ifdef __APPLE__
  setProperty(t, method, properties, "os.name", "Mac OS X");
#  else
  setProperty(t, method, properties, "os.name", "Linux");
#  endif
  setProperty(t, method, properties, "java.io.tmpdir", "/tmp");
  setProperty(t, method, properties, "user.home", getenv("HOME"));
  setProperty(t, method, properties, "user.dir", getenv("PWD"));
#endif

#ifdef __i386__
  setProperty(t, method, properties, "os.arch", "x86");
#elif defined __x86_64__
  setProperty(t, method, properties, "os.arch", "x86_64");
#elif defined(__ppc__) || defined(__powerpc__) \
  || defined(__ppc64__) || defined(__powerpc64__)
  setProperty(t, method, properties, "os.arch", "ppc");
#elif defined __ia64__
  setProperty(t, method, properties, "os.arch", "ia64");
#elif defined __arm__
  setProperty(t, method, properties, "os.arch", "arm");
#elif defined __alpha__
  setProperty(t, method, properties, "os.arch", "alpha");
#elif defined __sparc64__
  setProperty(t, method, properties, "os.arch", "sparc64");
#else
  setProperty(t, method, properties, "os.arch", "unknown");
#endif
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_gnu_classpath_VMStackWalker_getClassContext
(Thread* t, object, uintptr_t*)
{
  class Visitor: public Processor::StackVisitor {
   public:
    Visitor(Thread* t):
      t(t), skipCount(1), trace(0), index(0), protector(t, &trace)
    { }

    virtual bool visit(Processor::StackWalker* walker) {
      if (skipCount == 0) {
        if (trace == 0) {
          trace = makeObjectArray
            (t, arrayBody(t, t->m->types, Machine::ClassType),
             walker->count());
        }

        assert(t, index < objectArrayLength(t, trace));

        set(t, trace, ArrayBody + (index * BytesPerWord),
            methodClass(t, walker->method()));

        ++ index;
        return true;
      } else {
        -- skipCount;
        return true;
      }
    }

    Thread* t;
    unsigned skipCount;
    object trace;
    unsigned index;
    Thread::SingleProtector protector;
  } v(t);

  t->m->processor->walkStack(t, &v);

  if (v.trace == 0) {
    v.trace = makeObjectArray
      (t, arrayBody(t, t->m->types, Machine::ClassType), 0);
  }

  return reinterpret_cast<int64_t>(v.trace);
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_gnu_classpath_VMStackWalker_getClassLoader
(Thread* t, object, uintptr_t* arguments)
{
  return reinterpret_cast<int64_t>
    (classLoader(t, reinterpret_cast<object>(arguments[0])));
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMRuntime_mapLibraryName
(Thread* t, object, uintptr_t* arguments)
{
  object name = reinterpret_cast<object>(arguments[0]);
  PROTECT(t, name);

  const unsigned soPrefixLength = sizeof(SO_PREFIX) - 1;
  const unsigned nameLength = stringLength(t, name);
  const unsigned soSuffixLength = sizeof(SO_SUFFIX) - 1;
  const unsigned total = soPrefixLength + nameLength + soSuffixLength;

  object s = makeByteArray(t, total + 1);
  char* p = reinterpret_cast<char*>(&byteArrayBody(t, s, 0));

  memcpy(p, SO_PREFIX, soPrefixLength);
  stringChars(t, name, p + soPrefixLength);
  memcpy(p + soPrefixLength + nameLength, SO_SUFFIX, soSuffixLength);
  p[total] = 0;

  return reinterpret_cast<int64_t>(makeString(t, s, 0, total, 0));
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_System_arraycopy
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMSystem_arraycopy
(Thread* t, object, uintptr_t* arguments)
{
  Avian_java_lang_System_arraycopy(t, 0, arguments);
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_load
(Thread* t, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMRuntime_nativeLoad
(Thread* t, object, uintptr_t* arguments)
{
  object name = reinterpret_cast<object>(arguments[0]);

  // given that we set java.library.path to LIBRARY_PATH_SENTINAL, we
  // can determine which names are filenames and which are library
  // names by looking for the prefix LIBRARY_PATH_SENTINAL
  // FILE_SEPARATOR

  unsigned length = stringLength(t, name);
  char n[length + 1];
  stringChars(t, name, n);

  const unsigned pathPrefixLength
    = sizeof(LIBRARY_PATH_SENTINAL) - 1
    + sizeof(FILE_SEPARATOR) - 1;

  bool mapName = (strncmp(n, LIBRARY_PATH_SENTINAL FILE_SEPARATOR,
                          pathPrefixLength) == 0);
  if (mapName) {
    // strip the path prefix, SO prefix, and SO suffix before passing
    // the name to Runtime.load

    const unsigned soPrefixLength = sizeof(SO_PREFIX) - 1;
    const unsigned soSuffixLength = sizeof(SO_SUFFIX) - 1;
    const unsigned newOffset
      = stringOffset(t, name) + pathPrefixLength + soPrefixLength;
    const unsigned newLength
      = length - pathPrefixLength - soPrefixLength - soSuffixLength;

    name = makeString(t, stringData(t, name), newOffset, newLength, 0);
  }

  uintptr_t args[] = { reinterpret_cast<uintptr_t>(name), mapName };

  Avian_java_lang_Runtime_load(t, 0, args);

  if (t->exception) {
    t->exception = 0;
    return 0;
  } else {
    return 1;
  }
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_primitiveClass
(Thread* t, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_getPrimitiveClass
(Thread* t, object, uintptr_t* arguments)
{
  return Avian_java_lang_Class_primitiveClass(t, 0, arguments);
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_System_identityHashCode
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMSystem_identityHashCode
(Thread* t, object, uintptr_t* arguments)
{
  return Avian_java_lang_System_identityHashCode(t, 0, arguments);
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_gc
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMRuntime_gc
(Thread* t, object, uintptr_t*)
{
  Avian_java_lang_Runtime_gc(t, 0, 0);
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMRuntime_runFinalizationForExit
(Thread*, object, uintptr_t*)
{
  // ignore
}

extern "C" JNIEXPORT void JNICALL
Avian_java_lang_VMRuntime_exit
(Thread*, object, uintptr_t* arguments)
{
  exit(arguments[0]);
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findClass
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_loadClass
(Thread* t, object, uintptr_t* arguments)
{
  uintptr_t args[] = { 0, arguments[0] };

  return Avian_avian_SystemClassLoader_findClass(t, 0, args);
}

extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findLoadedClass
(Thread*, object, uintptr_t*);

extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_VMClassLoader_findLoadedClass
(Thread* t, object, uintptr_t* arguments)
{
  uintptr_t args[] = { 0, arguments[1] };

  return Avian_avian_SystemClassLoader_findLoadedClass(t, 0, args);
}
<|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2015 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project: Group-Share Filesystem
 *  Filename: gsfs.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hoojamis@gmail.com
 *  Date: Jun  4, 2015
 *  Time: 23:07:43
 *  Description: main function
 *****************************************************************************/

#include <iostream>
#include "option_parser.h"
#include "user_fs.h"
#include "fuse_interface.h"

int main(int argc, char** argv) {

    // parser options
    OptionParser parser;
    try {
        parser.parse(argc, argv);
    } catch (std::exception& err) {
        std::cerr << err.what() << std::endl;
        return 1;
    }

    /*
    std::cout << "is_master: " << parser.is_master << "\n"
              << "is_standby: " << parser.is_standby << "\n"
              << "address: " << parser.address << "\n"
              << "tcp port: " << parser.tcp_port << "\n"
              << "ssh port: " << parser.ssh_port << "\n"
              << "mount point: " << parser.mount_point << "\n"
              << "tmp dir: " << parser.tmp_dir << "\n";
    */

    if (!parser.is_master && !parser.is_standby) return 0;

    // init user fs
    UserFS fs;
    if (parser.is_master) fs.setMaster();

    // init dir tree
    try {
        fs.initDirTree(parser.mount_point, parser.tmp_dir);
    } catch (std::exception& err) {
        std::cerr << err.what() << std::endl;
        return 1;
    }

    // init host
    fs.initHost(parser.address, parser.tcp_port, parser.ssh_port);

    // init tcp network
    if (fs.initTCPNetwork(parser.address, parser.tcp_port)) {
        std::cerr << "Error when initializing TCP network. " << std::endl;
        return 1;
    }

    // init fuse interface
    FUSEInterface fuse;
    fuse.initialize(&fs);

    // copy arguments
    std::unique_ptr<char[]> argv1(new char[parser.mount_point.length() + 1]);
    parser.mount_point.copy(argv1.get(), parser.mount_point.length());
    argv1.get()[parser.mount_point.length()] = 0;

    char* fuse_args[2] = { argv[0], argv1.get() };

    return fuse_main(2, fuse_args, fuse.get(), 0);
}
<commit_msg>fix background bug<commit_after>/******************************************************************************
 *  Copyright (c) 2015 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project: Group-Share Filesystem
 *  Filename: gsfs.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hoojamis@gmail.com
 *  Date: Jun  4, 2015
 *  Time: 23:07:43
 *  Description: main function
 *****************************************************************************/

#include <iostream>
#include "option_parser.h"
#include "user_fs.h"
#include "fuse_interface.h"

int main(int argc, char** argv) {

    // parser options
    OptionParser parser;
    try {
        parser.parse(argc, argv);
    } catch (std::exception& err) {
        std::cerr << err.what() << std::endl;
        return 1;
    }

    if (!parser.is_master && !parser.is_standby) return 0;

    // init user fs
    UserFS fs;
    if (parser.is_master) fs.setMaster();

    // init dir tree
    try {
        fs.initDirTree(parser.mount_point, parser.tmp_dir);
    } catch (std::exception& err) {
        std::cerr << err.what() << std::endl;
        return 1;
    }

    // init host
    fs.initHost(parser.address, parser.tcp_port, parser.ssh_port);

    // init tcp network
    if (fs.initTCPNetwork(parser.address, parser.tcp_port)) {
        std::cerr << "Error when initializing TCP network. " << std::endl;
        return 1;
    }

    // init fuse interface
    FUSEInterface fuse;
    fuse.initialize(&fs);

    // copy arguments
    std::string arg_tmp = argv[0];
    std::vector<char> arg0(arg_tmp.begin(), arg_tmp.end());
    arg0.push_back(0);

    arg_tmp = parser.mount_point;
    std::vector<char> arg1(arg_tmp.begin(), arg_tmp.end());
    arg1.push_back(0);

    // We must run fuse foreground.
    // If not, fuse will fork() and the other threads in this process won't work.
    arg_tmp = "-f";
    std::vector<char> arg2(arg_tmp.begin(), arg_tmp.end());
    arg2.push_back(0);

    char* fuse_args[3] = { arg0.data(), arg1.data(), arg2.data() };

    return fuse_main(3, fuse_args, fuse.get(), 0);
}
<|endoftext|>


<commit_before>/**
 * @file   Type.hpp
 * @brief  Type utilities.
 * @author zer0
 * @date   2016-04-20
 */

#ifndef __INCLUDE_LIBTBAG__LIBTBAG_TYPE_HPP__
#define __INCLUDE_LIBTBAG__LIBTBAG_TYPE_HPP__

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#include <libtbag/config.h>
#include <libtbag/predef.hpp>

#include <cstddef>

#include <utility>
#include <memory>
#include <string>
#include <tuple>
#include <functional>
#include <type_traits>

#define STATIC_ASSERT_CHECK_TRAIT1(traits, type) \
    static_assert(traits<type>::value, #traits "<" #type ">::value");

#define STATIC_ASSERT_CHECK_TRAIT2(traits, type1, type2) \
    static_assert(traits<type1, type2>::value, #traits "<" #type1 "," #type2 ">::value");

#define STATIC_ASSERT_FULL_SUPPORTED_OPERATIONS(type)                     \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_constructible        , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_default_constructible, type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_copy_assignable      , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_move_constructible   , type)       \
    STATIC_ASSERT_CHECK_TRAIT2(std::is_assignable           , type, type) \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_copy_assignable      , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_move_assignable      , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_destructible         , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::has_virtual_destructor  , type)

#ifndef STATIC_ASSERT_CHECK_IS_BASE_OF
#define STATIC_ASSERT_CHECK_IS_BASE_OF(parent, derived) \
    static_assert(std::is_base_of<parent, derived>::value, "Not Derived " #parent " to " #derived)
#endif

#ifndef STATIC_ASSERT_CHECK_IS_SAME
#define STATIC_ASSERT_CHECK_IS_SAME(type1, type2) \
    static_assert(std::is_same<type1, type2>::value, #type1 " must be the same type as " #type2)
#endif

#ifndef STATIC_ASSERT_CHECK_IS_EQUALS
#define STATIC_ASSERT_CHECK_IS_EQUALS(value1, value2) \
    static_assert(value1 == value2, #value1 " and " #value2 " should be the same.")
#endif

#ifndef STATIC_ASSERT_INTEGER_EQUAL
#define STATIC_ASSERT_INTEGER_EQUAL(x, y) \
    STATIC_ASSERT_CHECK_IS_EQUALS((int)(x), (int)(y))
#endif

#ifndef STATIC_ASSERT_CHECK_SIZEOF
#define STATIC_ASSERT_CHECK_SIZEOF(type, value) \
    static_assert(sizeof(type) == value, "The size of the " #type " must be " #value ".")
#endif

#ifndef STATIC_ASSERT_CHECK_IS_DEFAULT_CONSTRUCTIBLE
#define STATIC_ASSERT_CHECK_IS_DEFAULT_CONSTRUCTIBLE(class_name)    \
    static_assert(std::is_default_constructible<class_name>::value, \
            "The " #class_name " class must support the default constructor.")
#endif

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

template <typename T, typename SharedType = T>
struct is_shared_ptr : public std::false_type
{ /* EMPTY. */ };

template <typename T>
struct is_shared_ptr<std::shared_ptr<T> > : public std::true_type
{ /* EMPTY. */ };

static_assert(is_shared_ptr<int>::value == false, "T is not std::shared_ptr type.");
static_assert(is_shared_ptr<std::shared_ptr<int> >::value, "T is std::shared_ptr type.");

/**
 * Remove const & reference.
 *
 * @remarks
 *  - First, remove reference,
 *  - Second, remove const.
 *
 * @author zer0
 * @date   2015-10-17
 * @date   2015-10-21 (Bug fix: Change transformation order)
 */
template <typename T>
struct remove_cr
{
    using __t0 = T;
    using __t1 = typename std::remove_reference<__t0>::type;
    using __t2 = typename std::remove_const<__t1>::type;
    using type = __t2;
};

/**
 * Remove const & reference & pointer.
 *
 * @remarks
 *  - First, remove reference,
 *  - Second, remove pointer,
 *  - Third, remove const.
 *
 * @author zer0
 * @date   2019-12-30
 */
template <typename T>
struct remove_cpr
{
    using __t0 = T;
    using __t1 = typename std::remove_reference<__t0>::type;
    using __t2 = typename std::remove_pointer<__t1>::type;
    using __t3 = typename std::remove_const<__t2>::type;
    using type = __t3;
};

/**
 * Tests for a string literal type.
 *
 * @remarks
 *  decltype("some string") of a string literal returns const char (&)[n] type.
 *
 * @author zer0
 * @date   2019-10-17
 */
template <typename T>
struct is_string_literal
{
    typedef typename remove_cr<T>::type __base_t;
    typedef typename std::add_lvalue_reference<const char [std::extent<__base_t>::value]>::type __test_t;

    TBAG_CONSTEXPR static bool value = std::is_same<T, __test_t>::value;
};

/**
 * Test that the first template argument is a string type.
 *
 * @author zer0
 * @date   2019-12-24
 */
template <typename ... T>
struct is_first_string;

template <typename Head, typename ... Tail>
struct is_first_string
{
    TBAG_CONSTEXPR static bool const value = is_first_string::value;
};

template <typename T>
struct is_first_string<T>
{
    TBAG_CONSTEXPR static bool const value =
            std::is_same<typename remove_cr<T>::type, std::string>::value ||
            is_string_literal<T>::value;
};

/**
 * Obtain the first template argument type.
 *
 * @author zer0
 * @date   2019-12-29
 */
template <typename ... T>
struct first_argument;

template <typename Head, typename ... Tail>
struct first_argument
{
    using type = Head;
};

template <typename T>
struct first_argument<T>
{
    using type = T;
};

/**
 * Test that all template arguments are of type integer.
 *
 * @author zer0
 * @date   2019-12-28
 */
template <typename ... T>
struct is_all_integral;

template <typename Head, typename ... Tail>
struct is_all_integral
{
    TBAG_CONSTEXPR static bool const value = is_all_integral::value && is_all_integral<Tail ...>::value;
};

template <typename T>
struct is_all_integral<T>
{
    TBAG_CONSTEXPR static bool const value = std::is_integral<typename remove_cr<T>::type>::value;
};

template <typename T>
struct function_traits;

template <typename RetT, typename ... ArgsT>
struct function_traits<RetT(ArgsT...)>
{
    TBAG_CONSTEXPR static std::size_t const argument_size = sizeof...(ArgsT);

    using return_type = RetT;
    using function_type = RetT(ArgsT...);

    template <std::size_t i>
    struct arguments
    {
        using type = typename std::tuple_element<i, std::tuple<ArgsT ...> >::type;
    };
};

template <typename RetT, typename ... ArgsT>
struct function_traits<RetT(*)(ArgsT...)> : public function_traits<RetT(ArgsT...)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<RetT(ClassT::*)(ArgsT...)> : public function_traits<RetT(ArgsT...)>
{
    using class_type = ClassT;
};

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<RetT(ClassT::*)(ArgsT...) const> : public function_traits<RetT(ArgsT...)>
{
    using class_type = ClassT;
};

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<RetT(ClassT::*)(ArgsT...) volatile> : public function_traits<RetT(ArgsT...)>
{
    using class_type = ClassT;
};

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<RetT(ClassT::*)(ArgsT...) volatile const> : public function_traits<RetT(ArgsT...)>
{
    using class_type = ClassT;
};

template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())>
{ /* EMPTY. */ };

template <typename T>
struct function_traits< std::function<T> > : public function_traits<T>
{ /* EMPTY. */ };

#if defined(_GLIBCXX_FUNCTIONAL)
# define _TBAG_MEM_FUNCTIONAL_TYPE std::_Mem_fn
#elif defined(_LIBCPP_FUNCTIONAL)
# define _TBAG_MEM_FUNCTIONAL_TYPE std::__mem_fn
#endif

#if defined(_TBAG_MEM_FUNCTIONAL_TYPE)
template <typename RetT, typename ClassT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)> >
        : public function_traits<RetT(ClassT*)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)(ArgsT...)> >
        : public function_traits<RetT(ClassT*, ArgsT...)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)(ArgsT...) const> >
        : public function_traits<RetT(const ClassT*, ArgsT...)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)(ArgsT...) volatile> >
        : public function_traits<RetT(volatile ClassT*, ArgsT...)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)(ArgsT...) volatile const> >
        : public function_traits<RetT(volatile const ClassT*, ArgsT...)>
{ /* EMPTY. */ };

#endif // _TBAG_MEM_FUNCTIONAL_TYPE

struct constexpr_init_t { /* EMPTY. */ };

TBAG_CONSTEXPR static constexpr_init_t const constexpr_init = {};

// Test assertion.
static_assert(!std::is_const<typename remove_cr<int const &>::type>::value
        , "It isn't non-const type.");
static_assert(!std::is_reference<typename remove_cr<int const &>::type>::value
        , "It isn't non-reference type.");

/**
 * Create a 2-dimensional trivial structure.
 *
 * @author zer0
 * @date   2015-10-21
 */
template <template <typename Tp> class TrivialType
        , typename T1
        , typename T2 = T1>
inline TBAG_CONSTEXPR TrivialType<typename remove_cr<T1>::type>
makeTrivial2(T1 && v1, T2 && v2) TBAG_NOEXCEPT
{
    typedef typename remove_cr<T1>::type __remove_cr;
    typedef TrivialType<__remove_cr> __trivial_type;
    return (__trivial_type{std::forward<T1>(v1), std::forward<T2>(v2)});
}

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

#endif // __INCLUDE_LIBTBAG__LIBTBAG_TYPE_HPP__

<commit_msg>Create is_complex template.<commit_after>/**
 * @file   Type.hpp
 * @brief  Type utilities.
 * @author zer0
 * @date   2016-04-20
 */

#ifndef __INCLUDE_LIBTBAG__LIBTBAG_TYPE_HPP__
#define __INCLUDE_LIBTBAG__LIBTBAG_TYPE_HPP__

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#include <libtbag/config.h>
#include <libtbag/predef.hpp>

#include <cstddef>

#include <utility>
#include <complex>
#include <memory>
#include <string>
#include <tuple>
#include <functional>
#include <type_traits>

#define STATIC_ASSERT_CHECK_TRAIT1(traits, type) \
    static_assert(traits<type>::value, #traits "<" #type ">::value");

#define STATIC_ASSERT_CHECK_TRAIT2(traits, type1, type2) \
    static_assert(traits<type1, type2>::value, #traits "<" #type1 "," #type2 ">::value");

#define STATIC_ASSERT_FULL_SUPPORTED_OPERATIONS(type)                     \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_constructible        , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_default_constructible, type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_copy_assignable      , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_move_constructible   , type)       \
    STATIC_ASSERT_CHECK_TRAIT2(std::is_assignable           , type, type) \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_copy_assignable      , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_move_assignable      , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::is_destructible         , type)       \
    STATIC_ASSERT_CHECK_TRAIT1(std::has_virtual_destructor  , type)

#ifndef STATIC_ASSERT_CHECK_IS_BASE_OF
#define STATIC_ASSERT_CHECK_IS_BASE_OF(parent, derived) \
    static_assert(std::is_base_of<parent, derived>::value, "Not Derived " #parent " to " #derived)
#endif

#ifndef STATIC_ASSERT_CHECK_IS_SAME
#define STATIC_ASSERT_CHECK_IS_SAME(type1, type2) \
    static_assert(std::is_same<type1, type2>::value, #type1 " must be the same type as " #type2)
#endif

#ifndef STATIC_ASSERT_CHECK_IS_EQUALS
#define STATIC_ASSERT_CHECK_IS_EQUALS(value1, value2) \
    static_assert(value1 == value2, #value1 " and " #value2 " should be the same.")
#endif

#ifndef STATIC_ASSERT_INTEGER_EQUAL
#define STATIC_ASSERT_INTEGER_EQUAL(x, y) \
    STATIC_ASSERT_CHECK_IS_EQUALS((int)(x), (int)(y))
#endif

#ifndef STATIC_ASSERT_CHECK_SIZEOF
#define STATIC_ASSERT_CHECK_SIZEOF(type, value) \
    static_assert(sizeof(type) == value, "The size of the " #type " must be " #value ".")
#endif

#ifndef STATIC_ASSERT_CHECK_IS_DEFAULT_CONSTRUCTIBLE
#define STATIC_ASSERT_CHECK_IS_DEFAULT_CONSTRUCTIBLE(class_name)    \
    static_assert(std::is_default_constructible<class_name>::value, \
            "The " #class_name " class must support the default constructor.")
#endif

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

// Test std::shared_ptr

template <typename T, typename SharedType = T>
struct is_shared_ptr : public std::false_type
{ /* EMPTY. */ };

template <typename T>
struct is_shared_ptr< std::shared_ptr<T> > : public std::true_type
{ /* EMPTY. */ };

static_assert(!is_shared_ptr<int>::value, "T is not std::shared_ptr type.");
static_assert(is_shared_ptr< std::shared_ptr<int> >::value, "T is std::shared_ptr type.");

// Test std::complex

template <typename T, typename SharedType = T>
struct is_complex : public std::false_type
{ /* EMPTY. */ };

template <typename T>
struct is_complex< std::complex<T> > : public std::true_type
{ /* EMPTY. */ };

static_assert(!is_complex<float>::value, "T is not std::complex type.");
static_assert(is_complex< std::complex<float> >::value, "T is std::complex type.");

/**
 * Remove const & reference.
 *
 * @remarks
 *  - First, remove reference,
 *  - Second, remove const.
 *
 * @author zer0
 * @date   2015-10-17
 * @date   2015-10-21 (Bug fix: Change transformation order)
 */
template <typename T>
struct remove_cr
{
    using __t0 = T;
    using __t1 = typename std::remove_reference<__t0>::type;
    using __t2 = typename std::remove_const<__t1>::type;
    using type = __t2;
};

/**
 * Remove const & reference & pointer.
 *
 * @remarks
 *  - First, remove reference,
 *  - Second, remove pointer,
 *  - Third, remove const.
 *
 * @author zer0
 * @date   2019-12-30
 */
template <typename T>
struct remove_cpr
{
    using __t0 = T;
    using __t1 = typename std::remove_reference<__t0>::type;
    using __t2 = typename std::remove_pointer<__t1>::type;
    using __t3 = typename std::remove_const<__t2>::type;
    using type = __t3;
};

/**
 * Tests for a string literal type.
 *
 * @remarks
 *  decltype("some string") of a string literal returns const char (&)[n] type.
 *
 * @author zer0
 * @date   2019-10-17
 */
template <typename T>
struct is_string_literal
{
    typedef typename remove_cr<T>::type __base_t;
    typedef typename std::add_lvalue_reference<const char [std::extent<__base_t>::value]>::type __test_t;

    TBAG_CONSTEXPR static bool value = std::is_same<T, __test_t>::value;
};

/**
 * Test that the first template argument is a string type.
 *
 * @author zer0
 * @date   2019-12-24
 */
template <typename ... T>
struct is_first_string;

template <typename Head, typename ... Tail>
struct is_first_string
{
    TBAG_CONSTEXPR static bool const value = is_first_string::value;
};

template <typename T>
struct is_first_string<T>
{
    TBAG_CONSTEXPR static bool const value =
            std::is_same<typename remove_cr<T>::type, std::string>::value ||
            is_string_literal<T>::value;
};

/**
 * Obtain the first template argument type.
 *
 * @author zer0
 * @date   2019-12-29
 */
template <typename ... T>
struct first_argument;

template <typename Head, typename ... Tail>
struct first_argument
{
    using type = Head;
};

template <typename T>
struct first_argument<T>
{
    using type = T;
};

/**
 * Test that all template arguments are of type integer.
 *
 * @author zer0
 * @date   2019-12-28
 */
template <typename ... T>
struct is_all_integral;

template <typename Head, typename ... Tail>
struct is_all_integral
{
    TBAG_CONSTEXPR static bool const value = is_all_integral::value && is_all_integral<Tail ...>::value;
};

template <typename T>
struct is_all_integral<T>
{
    TBAG_CONSTEXPR static bool const value = std::is_integral<typename remove_cr<T>::type>::value;
};

template <typename T>
struct function_traits;

template <typename RetT, typename ... ArgsT>
struct function_traits<RetT(ArgsT...)>
{
    TBAG_CONSTEXPR static std::size_t const argument_size = sizeof...(ArgsT);

    using return_type = RetT;
    using function_type = RetT(ArgsT...);

    template <std::size_t i>
    struct arguments
    {
        using type = typename std::tuple_element<i, std::tuple<ArgsT ...> >::type;
    };
};

template <typename RetT, typename ... ArgsT>
struct function_traits<RetT(*)(ArgsT...)> : public function_traits<RetT(ArgsT...)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<RetT(ClassT::*)(ArgsT...)> : public function_traits<RetT(ArgsT...)>
{
    using class_type = ClassT;
};

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<RetT(ClassT::*)(ArgsT...) const> : public function_traits<RetT(ArgsT...)>
{
    using class_type = ClassT;
};

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<RetT(ClassT::*)(ArgsT...) volatile> : public function_traits<RetT(ArgsT...)>
{
    using class_type = ClassT;
};

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<RetT(ClassT::*)(ArgsT...) volatile const> : public function_traits<RetT(ArgsT...)>
{
    using class_type = ClassT;
};

template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())>
{ /* EMPTY. */ };

template <typename T>
struct function_traits< std::function<T> > : public function_traits<T>
{ /* EMPTY. */ };

#if defined(_GLIBCXX_FUNCTIONAL)
# define _TBAG_MEM_FUNCTIONAL_TYPE std::_Mem_fn
#elif defined(_LIBCPP_FUNCTIONAL)
# define _TBAG_MEM_FUNCTIONAL_TYPE std::__mem_fn
#endif

#if defined(_TBAG_MEM_FUNCTIONAL_TYPE)
template <typename RetT, typename ClassT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)> >
        : public function_traits<RetT(ClassT*)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)(ArgsT...)> >
        : public function_traits<RetT(ClassT*, ArgsT...)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)(ArgsT...) const> >
        : public function_traits<RetT(const ClassT*, ArgsT...)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)(ArgsT...) volatile> >
        : public function_traits<RetT(volatile ClassT*, ArgsT...)>
{ /* EMPTY. */ };

template <typename RetT, typename ClassT, typename ... ArgsT>
struct function_traits<_TBAG_MEM_FUNCTIONAL_TYPE<RetT(ClassT::*)(ArgsT...) volatile const> >
        : public function_traits<RetT(volatile const ClassT*, ArgsT...)>
{ /* EMPTY. */ };

#endif // _TBAG_MEM_FUNCTIONAL_TYPE

struct constexpr_init_t { /* EMPTY. */ };

TBAG_CONSTEXPR static constexpr_init_t const constexpr_init = {};

// Test assertion.
static_assert(!std::is_const<typename remove_cr<int const &>::type>::value
        , "It isn't non-const type.");
static_assert(!std::is_reference<typename remove_cr<int const &>::type>::value
        , "It isn't non-reference type.");

/**
 * Create a 2-dimensional trivial structure.
 *
 * @author zer0
 * @date   2015-10-21
 */
template <template <typename Tp> class TrivialType
        , typename T1
        , typename T2 = T1>
inline TBAG_CONSTEXPR TrivialType<typename remove_cr<T1>::type>
makeTrivial2(T1 && v1, T2 && v2) TBAG_NOEXCEPT
{
    typedef typename remove_cr<T1>::type __remove_cr;
    typedef TrivialType<__remove_cr> __trivial_type;
    return (__trivial_type{std::forward<T1>(v1), std::forward<T2>(v2)});
}

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

#endif // __INCLUDE_LIBTBAG__LIBTBAG_TYPE_HPP__

<|endoftext|>


<commit_before>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#include <hpp/core/weighed-distance.hh>

#include <limits>

#include <Eigen/SVD>

#include <pinocchio/algorithm/joint-configuration.hpp>
#include <pinocchio/algorithm/jacobian.hpp>
#include <pinocchio/multibody/geometry.hpp>

#include <hpp/util/debug.hh>
#include <hpp/pinocchio/body.hh>
#include <hpp/pinocchio/device.hh>
#include <hpp/pinocchio/joint.hh>
#include <hpp/pinocchio/liegroup.hh>

#include <hpp/core/problem.hh>

namespace hpp {
  namespace core {
    namespace {
      struct ComputeWeightStep : public se3::fusion::JointModelVisitor<ComputeWeightStep>
      {
        typedef boost::fusion::vector<const se3::Model &,
                                      const se3::Data &,
                                      const se3::GeometryData &,
                                      value_type & > ArgsType;

        JOINT_MODEL_VISITOR_INIT(ComputeWeightStep);

        template<int N> static value_type largestSingularValue (const Eigen::Matrix<value_type, 3, N>& m)
        {
          typedef Eigen::Matrix<value_type, 3, N> M;
          typedef Eigen::JacobiSVD<M> SVD_t;
          SVD_t svd (m);
          return svd.singularValues()[0];
        }

        template<typename JointModel, int NR> static void getRotationSubJacobian (
            const se3::JointModelBase<JointModel> & jmodel,
            const se3::Data & data,
            const Eigen::Matrix<value_type, 6, Eigen::Dynamic>& J,
            const se3::JointIndex& j,
            Eigen::Matrix<value_type, 6, NR>& rBlock)
        {
          typedef typename pinocchio::LieGroupTpl::template operation<JointModel>::type LGOp_t;
          typedef Eigen::Matrix<value_type, 6, JointModel::NV>  Block_t;
          Block_t block;
          // Linear part
          block.template topRows   <3>() = data.oMi[j].rotation() * J.block<3, JointModel::NV>(0, jmodel.idx_v());
          // Angular part
          block.template bottomRows<3>() = data.oMi[j].rotation() * J.block<3, JointModel::NV>(3, jmodel.idx_v());

          LGOp_t::getRotationSubJacobian(block, rBlock);
        }

        template<int NR> static value_type computeWeight (
            const Eigen::Matrix<value_type, 6, NR>& rBlock,
            const value_type& r)
        {
          value_type linear_sigma  = largestSingularValue<NR>(rBlock.template topRows<3>());
          value_type angular_sigma = largestSingularValue<NR>(rBlock.template bottomRows<3>());

          return std::max(linear_sigma, r * angular_sigma);
        }

        template<typename JointModel>
        static void algo(const se3::JointModelBase<JointModel> & jmodel,
            const se3::Model & model,
            const se3::Data & data,
            const se3::GeometryData & geomData,
            value_type & length)
        {
          typedef typename pinocchio::LieGroupTpl::template operation<JointModel>::type LGOp_t;
          typedef Eigen::Matrix<value_type, 6, LGOp_t::NR    > RBlock_t;

          if (LGOp_t::NR == 0) {
            length = 1;
            return;
          }

          const se3::JointIndex i = jmodel.id();
          JointJacobian_t jacobian(6, data.J.cols());
          RBlock_t rBlock;
          value_type sigma;
          for (se3::JointIndex j = i; j <= (se3::JointIndex)data.lastChild[i]; ++j)
          {
            se3::getJacobian<true>(model, data, j, jacobian);
            getRotationSubJacobian(jmodel, data, jacobian, j, rBlock);
            const value_type radius = geomData.radius[j]
              + (data.oMi[j].translation() - data.oMi[i].translation()).squaredNorm();
            sigma = computeWeight(rBlock, radius);
            if (length < sigma) length = sigma;
          }
        }
      };

      template <> void ComputeWeightStep::algo<se3::JointModelComposite>(
          const se3::JointModelBase<se3::JointModelComposite> & jmodel,
          const se3::Model & model,
          const se3::Data & data,
          const se3::GeometryData & geomData,
          value_type & length)
      {
        hppDout(warning, "The weights for JointModelComposite are not correct."
            " There should be one weight per subjoint.");
        length = 0;
        value_type tmp = 0;
        for (size_t i = 0; i < jmodel.derived().joints.size(); ++i) {
          ComputeWeightStep::run(jmodel.derived().joints[i], ArgsType(model, data, geomData, tmp));
          length += tmp;
        }
      }

      template<> value_type ComputeWeightStep::largestSingularValue<0>(const Eigen::Matrix<value_type, 3, 0>&)
      {
        return 0;
      }

      template<> value_type ComputeWeightStep::largestSingularValue<1>(const Eigen::Matrix<value_type, 3, 1>& m)
      {
        return m.norm();
      }

      struct SquaredDistanceStep : public se3::fusion::JointModelVisitor<SquaredDistanceStep>
      {
        typedef boost::fusion::vector<ConfigurationIn_t,
                ConfigurationIn_t,
                const value_type,
                value_type &> ArgsType;

        JOINT_MODEL_VISITOR_INIT(SquaredDistanceStep);

        template<typename JointModel>
        static void algo(const se3::JointModelBase<JointModel> & jmodel,
            ConfigurationIn_t q0,
            ConfigurationIn_t q1,
            const value_type & w,
            value_type & distance)
        {
          distance = ::hpp::pinocchio::LieGroupTpl::template operation<JointModel>::type
            ::squaredDistance(
                jmodel.jointConfigSelector(q0),
                jmodel.jointConfigSelector(q1),
                w);
        }

      };

      template <>
      void SquaredDistanceStep::algo<se3::JointModelComposite>(
          const se3::JointModelBase<se3::JointModelComposite> & jmodel,
          ConfigurationIn_t q0,
          ConfigurationIn_t q1,
          const value_type & w,
          value_type & distance)
      {
        se3::details::Dispatch<SquaredDistanceStep>::run(
            jmodel.derived(),
            ArgsType(q0, q1, w, distance));
      }
    }

    std::ostream& operator<< (std::ostream& os, const std::vector <value_type>& v)
    {
      for (std::size_t i=0; i<v.size (); ++i) {
	os << v [i] << ",";
      }
      return os;
    }

    WeighedDistancePtr_t WeighedDistance::create (const DevicePtr_t& robot)
    {
      WeighedDistance* ptr = new WeighedDistance (robot);
      WeighedDistancePtr_t shPtr (ptr);
      ptr->init (shPtr);
      return shPtr;
    }

    WeighedDistancePtr_t WeighedDistance::createFromProblem
    (const Problem& problem)
    {
      WeighedDistance* ptr = new WeighedDistance (problem);
      WeighedDistancePtr_t shPtr (ptr);
      ptr->init (shPtr);
      return shPtr;
    }

    WeighedDistancePtr_t
    WeighedDistance::createWithWeight (const DevicePtr_t& robot,
			     const std::vector <value_type>& weights)
    {
      WeighedDistance* ptr = new WeighedDistance (robot, weights);
      WeighedDistancePtr_t shPtr (ptr);
      ptr->init (shPtr);
      return shPtr;
    }

    WeighedDistancePtr_t WeighedDistance::createCopy
	(const WeighedDistancePtr_t& distance)
    {
      WeighedDistance* ptr = new WeighedDistance (*distance);
      WeighedDistancePtr_t shPtr (ptr);
      ptr->init (shPtr);
      return shPtr;
    }

    DistancePtr_t WeighedDistance::clone () const
    {
      return createCopy (weak_.lock ());
    }

    value_type WeighedDistance::getWeight( std::size_t rank ) const
    {
      return weights_[rank];
    }

    void WeighedDistance::setWeight (std::size_t rank, value_type weight )
    {
      if ( rank < weights_.size() )
      {
	weights_[rank] = weight;
      }
      else {
	std::ostringstream oss;
	oss << "Distance::setWeight : rank " << rank << " is out of range ("
	    << weights_.size () << ").";
	throw std::runtime_error(oss.str ());
      }
    }

    void WeighedDistance::computeWeights ()
    {
      // Store computation flag
      Device_t::Computation_t flag = robot_->computationFlag ();
      Device_t::Computation_t newflag = static_cast <Device_t::Computation_t>
	(flag | Device_t::JACOBIAN);
      robot_->controlComputation (newflag);
      robot_->computeForwardKinematics ();
      robot_->controlComputation (flag);
      value_type minLength = std::numeric_limits <value_type>::infinity ();

      JointJacobian_t jacobian(6, robot_->numberDof());
      const se3::Model& model = robot_->model();
      const se3::Data& data = robot_->data();
      const se3::GeometryData& geomData = robot_->geomData();
      for (se3::JointIndex i = 1; i < model.joints.size(); ++i)
      {
	  value_type length = 0;
          ComputeWeightStep::run(model.joints[i],
              ComputeWeightStep::ArgsType(model, data, geomData, length));
	  if (minLength > length && length > 0) minLength = length;
	  weights_.push_back (length);
	for (std::size_t k=0; k < weights_.size (); ++k) {
	  if (weights_ [k] == 0) {
	    weights_ [k] = minLength;
	  }
	}
      }
      hppDout(info, "The weights are " << Eigen::Map<vector_t>(weights_.data(), weights_.size()).transpose());
    }

    WeighedDistance::WeighedDistance (const DevicePtr_t& robot) :
      robot_ (robot), weights_ ()
    {
      computeWeights ();
    }

    WeighedDistance::WeighedDistance (const Problem& problem) :
      robot_ (problem.robot()), weights_ ()
    {
      computeWeights ();
    }

    WeighedDistance::WeighedDistance (const DevicePtr_t& robot,
				      const std::vector <value_type>& weights) :
      robot_ (robot), weights_ (weights)
    {
    }

    WeighedDistance::WeighedDistance (const WeighedDistance& distance) :
      robot_ (distance.robot_),
      weights_ (distance.weights_)
    {
    }

    void WeighedDistance::init (WeighedDistanceWkPtr_t self)
    {
      weak_ = self;
    }

    value_type WeighedDistance::impl_distance (ConfigurationIn_t q1,
					       ConfigurationIn_t q2) const
    {
      value_type res = 0, d;

      const pinocchio::Model& model = robot_->model();
      assert (model.joints.size() <= weights_.size () + 1);
      // Configuration_t qq1 (q1), qq2 (q2);
      // Loop over robot joint
      for( se3::JointIndex i=1; i<(se3::JointIndex) model.njoints; ++i )
      {
        value_type length = weights_ [i-1] * weights_ [i-1];
        SquaredDistanceStep::ArgsType args(q1, q2, length, d);
        SquaredDistanceStep::run(model.joints[i], args);
        res += d;
      }
      res+=(q1 - q2).tail (robot_->extraConfigSpace ().dimension()).squaredNorm ();
      return sqrt (res);
    }
  } //   namespace core
} // namespace hpp
<commit_msg>Fix compilation (changes in se3::getJacobian)<commit_after>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#include <hpp/core/weighed-distance.hh>

#include <limits>

#include <Eigen/SVD>

#include <pinocchio/algorithm/joint-configuration.hpp>
#include <pinocchio/algorithm/jacobian.hpp>
#include <pinocchio/multibody/geometry.hpp>

#include <hpp/util/debug.hh>
#include <hpp/pinocchio/body.hh>
#include <hpp/pinocchio/device.hh>
#include <hpp/pinocchio/joint.hh>
#include <hpp/pinocchio/liegroup.hh>

#include <hpp/core/problem.hh>

namespace hpp {
  namespace core {
    namespace {
      struct ComputeWeightStep : public se3::fusion::JointModelVisitor<ComputeWeightStep>
      {
        typedef boost::fusion::vector<const se3::Model &,
                                      const se3::Data &,
                                      const se3::GeometryData &,
                                      value_type & > ArgsType;

        JOINT_MODEL_VISITOR_INIT(ComputeWeightStep);

        template<int N> static value_type largestSingularValue (const Eigen::Matrix<value_type, 3, N>& m)
        {
          typedef Eigen::Matrix<value_type, 3, N> M;
          typedef Eigen::JacobiSVD<M> SVD_t;
          SVD_t svd (m);
          return svd.singularValues()[0];
        }

        template<typename JointModel, int NR> static void getRotationSubJacobian (
            const se3::JointModelBase<JointModel> & jmodel,
            const se3::Data & data,
            const Eigen::Matrix<value_type, 6, Eigen::Dynamic>& J,
            const se3::JointIndex& j,
            Eigen::Matrix<value_type, 6, NR>& rBlock)
        {
          typedef typename pinocchio::LieGroupTpl::template operation<JointModel>::type LGOp_t;
          typedef Eigen::Matrix<value_type, 6, JointModel::NV>  Block_t;
          Block_t block;
          // Linear part
          block.template topRows   <3>() = data.oMi[j].rotation() * J.block<3, JointModel::NV>(0, jmodel.idx_v());
          // Angular part
          block.template bottomRows<3>() = data.oMi[j].rotation() * J.block<3, JointModel::NV>(3, jmodel.idx_v());

          LGOp_t::getRotationSubJacobian(block, rBlock);
        }

        template<int NR> static value_type computeWeight (
            const Eigen::Matrix<value_type, 6, NR>& rBlock,
            const value_type& r)
        {
          value_type linear_sigma  = largestSingularValue<NR>(rBlock.template topRows<3>());
          value_type angular_sigma = largestSingularValue<NR>(rBlock.template bottomRows<3>());

          return std::max(linear_sigma, r * angular_sigma);
        }

        template<typename JointModel>
        static void algo(const se3::JointModelBase<JointModel> & jmodel,
            const se3::Model & model,
            const se3::Data & data,
            const se3::GeometryData & geomData,
            value_type & length)
        {
          typedef typename pinocchio::LieGroupTpl::template operation<JointModel>::type LGOp_t;
          typedef Eigen::Matrix<value_type, 6, LGOp_t::NR    > RBlock_t;

          if (LGOp_t::NR == 0) {
            length = 1;
            return;
          }

          const se3::JointIndex i = jmodel.id();
          JointJacobian_t jacobian(6, data.J.cols());
          RBlock_t rBlock;
          value_type sigma;
          for (se3::JointIndex j = i; j <= (se3::JointIndex)data.lastChild[i]; ++j)
          {
            se3::getJacobian<se3::LOCAL>(model, data, j, jacobian);
            getRotationSubJacobian(jmodel, data, jacobian, j, rBlock);
            const value_type radius = geomData.radius[j]
              + (data.oMi[j].translation() - data.oMi[i].translation()).squaredNorm();
            sigma = computeWeight(rBlock, radius);
            if (length < sigma) length = sigma;
          }
        }
      };

      template <> void ComputeWeightStep::algo<se3::JointModelComposite>(
          const se3::JointModelBase<se3::JointModelComposite> & jmodel,
          const se3::Model & model,
          const se3::Data & data,
          const se3::GeometryData & geomData,
          value_type & length)
      {
        hppDout(warning, "The weights for JointModelComposite are not correct."
            " There should be one weight per subjoint.");
        length = 0;
        value_type tmp = 0;
        for (size_t i = 0; i < jmodel.derived().joints.size(); ++i) {
          ComputeWeightStep::run(jmodel.derived().joints[i], ArgsType(model, data, geomData, tmp));
          length += tmp;
        }
      }

      template<> value_type ComputeWeightStep::largestSingularValue<0>(const Eigen::Matrix<value_type, 3, 0>&)
      {
        return 0;
      }

      template<> value_type ComputeWeightStep::largestSingularValue<1>(const Eigen::Matrix<value_type, 3, 1>& m)
      {
        return m.norm();
      }

      struct SquaredDistanceStep : public se3::fusion::JointModelVisitor<SquaredDistanceStep>
      {
        typedef boost::fusion::vector<ConfigurationIn_t,
                ConfigurationIn_t,
                const value_type,
                value_type &> ArgsType;

        JOINT_MODEL_VISITOR_INIT(SquaredDistanceStep);

        template<typename JointModel>
        static void algo(const se3::JointModelBase<JointModel> & jmodel,
            ConfigurationIn_t q0,
            ConfigurationIn_t q1,
            const value_type & w,
            value_type & distance)
        {
          distance = ::hpp::pinocchio::LieGroupTpl::template operation<JointModel>::type
            ::squaredDistance(
                jmodel.jointConfigSelector(q0),
                jmodel.jointConfigSelector(q1),
                w);
        }

      };

      template <>
      void SquaredDistanceStep::algo<se3::JointModelComposite>(
          const se3::JointModelBase<se3::JointModelComposite> & jmodel,
          ConfigurationIn_t q0,
          ConfigurationIn_t q1,
          const value_type & w,
          value_type & distance)
      {
        se3::details::Dispatch<SquaredDistanceStep>::run(
            jmodel.derived(),
            ArgsType(q0, q1, w, distance));
      }
    }

    std::ostream& operator<< (std::ostream& os, const std::vector <value_type>& v)
    {
      for (std::size_t i=0; i<v.size (); ++i) {
	os << v [i] << ",";
      }
      return os;
    }

    WeighedDistancePtr_t WeighedDistance::create (const DevicePtr_t& robot)
    {
      WeighedDistance* ptr = new WeighedDistance (robot);
      WeighedDistancePtr_t shPtr (ptr);
      ptr->init (shPtr);
      return shPtr;
    }

    WeighedDistancePtr_t WeighedDistance::createFromProblem
    (const Problem& problem)
    {
      WeighedDistance* ptr = new WeighedDistance (problem);
      WeighedDistancePtr_t shPtr (ptr);
      ptr->init (shPtr);
      return shPtr;
    }

    WeighedDistancePtr_t
    WeighedDistance::createWithWeight (const DevicePtr_t& robot,
			     const std::vector <value_type>& weights)
    {
      WeighedDistance* ptr = new WeighedDistance (robot, weights);
      WeighedDistancePtr_t shPtr (ptr);
      ptr->init (shPtr);
      return shPtr;
    }

    WeighedDistancePtr_t WeighedDistance::createCopy
	(const WeighedDistancePtr_t& distance)
    {
      WeighedDistance* ptr = new WeighedDistance (*distance);
      WeighedDistancePtr_t shPtr (ptr);
      ptr->init (shPtr);
      return shPtr;
    }

    DistancePtr_t WeighedDistance::clone () const
    {
      return createCopy (weak_.lock ());
    }

    value_type WeighedDistance::getWeight( std::size_t rank ) const
    {
      return weights_[rank];
    }

    void WeighedDistance::setWeight (std::size_t rank, value_type weight )
    {
      if ( rank < weights_.size() )
      {
	weights_[rank] = weight;
      }
      else {
	std::ostringstream oss;
	oss << "Distance::setWeight : rank " << rank << " is out of range ("
	    << weights_.size () << ").";
	throw std::runtime_error(oss.str ());
      }
    }

    void WeighedDistance::computeWeights ()
    {
      // Store computation flag
      Device_t::Computation_t flag = robot_->computationFlag ();
      Device_t::Computation_t newflag = static_cast <Device_t::Computation_t>
	(flag | Device_t::JACOBIAN);
      robot_->controlComputation (newflag);
      robot_->computeForwardKinematics ();
      robot_->controlComputation (flag);
      value_type minLength = std::numeric_limits <value_type>::infinity ();

      JointJacobian_t jacobian(6, robot_->numberDof());
      const se3::Model& model = robot_->model();
      const se3::Data& data = robot_->data();
      const se3::GeometryData& geomData = robot_->geomData();
      for (se3::JointIndex i = 1; i < model.joints.size(); ++i)
      {
	  value_type length = 0;
          ComputeWeightStep::run(model.joints[i],
              ComputeWeightStep::ArgsType(model, data, geomData, length));
	  if (minLength > length && length > 0) minLength = length;
	  weights_.push_back (length);
	for (std::size_t k=0; k < weights_.size (); ++k) {
	  if (weights_ [k] == 0) {
	    weights_ [k] = minLength;
	  }
	}
      }
      hppDout(info, "The weights are " << Eigen::Map<vector_t>(weights_.data(), weights_.size()).transpose());
    }

    WeighedDistance::WeighedDistance (const DevicePtr_t& robot) :
      robot_ (robot), weights_ ()
    {
      computeWeights ();
    }

    WeighedDistance::WeighedDistance (const Problem& problem) :
      robot_ (problem.robot()), weights_ ()
    {
      computeWeights ();
    }

    WeighedDistance::WeighedDistance (const DevicePtr_t& robot,
				      const std::vector <value_type>& weights) :
      robot_ (robot), weights_ (weights)
    {
    }

    WeighedDistance::WeighedDistance (const WeighedDistance& distance) :
      robot_ (distance.robot_),
      weights_ (distance.weights_)
    {
    }

    void WeighedDistance::init (WeighedDistanceWkPtr_t self)
    {
      weak_ = self;
    }

    value_type WeighedDistance::impl_distance (ConfigurationIn_t q1,
					       ConfigurationIn_t q2) const
    {
      value_type res = 0, d;

      const pinocchio::Model& model = robot_->model();
      assert (model.joints.size() <= weights_.size () + 1);
      // Configuration_t qq1 (q1), qq2 (q2);
      // Loop over robot joint
      for( se3::JointIndex i=1; i<(se3::JointIndex) model.njoints; ++i )
      {
        value_type length = weights_ [i-1] * weights_ [i-1];
        SquaredDistanceStep::ArgsType args(q1, q2, length, d);
        SquaredDistanceStep::run(model.joints[i], args);
        res += d;
      }
      res+=(q1 - q2).tail (robot_->extraConfigSpace ().dimension()).squaredNorm ();
      return sqrt (res);
    }
  } //   namespace core
} // namespace hpp
<|endoftext|>


<commit_before>#include "virtualview.hpp"

#include <QGLBuilder>
#include <QGLSceneNode>
#include <QGLAbstractScene>
#include <QMessageBox>
#include <QGraphicsPixmapItem>
#include <QtGui\QMouseEvent>

#include <GoBoard.h>

VirtualView::VirtualView(QWidget *parent){
    this->setParent(parent);

    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->resize(parent->size());

    this->setMouseTracking(true);
    this->setting_stone_valid = false;

    // directories of the images
    QString texture_path = "res/textures/";
    QString board_directory_size9 = QString(texture_path + "go_board_" + QString::number(9)+".png");
    QString board_directory_size13 = QString(texture_path + "go_board_" + QString::number(13)+".png");
    QString board_directory_size19 = QString(texture_path + "go_board_" + QString::number(19)+".png");
    QString black_stone_directory = QString(texture_path + "black_stone.png");
    QString white_stone_directory = QString(texture_path + "white_stone.png");

    // loads the images and checks if the image could loaded
    board_image_size9 = QImage(board_directory_size9);
    board_image_size13 = QImage(board_directory_size13);
    board_image_size19 = QImage(board_directory_size19);
    black_stone_image = QImage(black_stone_directory);
    white_stone_image = QImage(white_stone_directory);

}
VirtualView::~VirtualView(){
}

void VirtualView::createAndSetScene(QSize size, const GoBoard * game_board)
{
    if (game_board == nullptr)
        return;

    this->resize(size);

    scene.clear();
    scene.setSceneRect(0,0, size.width(), size.height());
    fitInView(this->sceneRect());

    // loads the board size and checks if its a valid size
    board_size = game_board->Size();

    QImage board_image;

    switch(board_size){
    case 9:
        board_image = board_image_size9;
        break;
    case 13:
        board_image = board_image_size13;
        break;
    case 19:
        board_image = board_image_size19;
        break;
    default:
        QMessageBox::warning(this, "board size error", "invalid size of the board!");
    }

    if (board_image.isNull())
        QMessageBox::warning(this, "file loading error", "could not load board image!");
    if (black_stone_image.isNull())
        QMessageBox::warning(this, "file loading error", "could not load black stone image!");
    if (white_stone_image.isNull())
        QMessageBox::warning(this, "file loading error", "could not laod white stone image!");

    // scale_x and scale_y are the scaling factors of the virtual board
    float scale_x = size.width() / float(board_image.width());
    float scale_y = size.height() / float(board_image.height());

    cell_width = static_cast<qreal>(board_image.width()) / (board_size+1);
    cell_height = static_cast<qreal>(board_image.height()) / (board_size+1);

    // scale the images to the right size
    QPixmap board_image_scaled = QPixmap::fromImage(board_image);
    board_image_scaled = board_image_scaled.scaled(size.width(),size.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    QPixmap black_stone_image_scaled = QPixmap::fromImage(black_stone_image);
    black_stone_image_scaled = black_stone_image_scaled.scaled(black_stone_image.width()*scale_x, black_stone_image.height()*scale_y, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    QPixmap white_stone_image_scaled = QPixmap::fromImage(white_stone_image);
    white_stone_image_scaled = white_stone_image_scaled.scaled(white_stone_image.width()*scale_x, white_stone_image.height()*scale_y, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    if (board_image_scaled.isNull())
        QMessageBox::warning(this, "image scale error", "could not scale board!");
    if (black_stone_image_scaled.isNull())
        QMessageBox::warning(this, "image scale error", "could not scale black stone!");
    if (white_stone_image_scaled.isNull())
        QMessageBox::warning(this, "image scale error", "could not scale white stone!");

    // add the board image to the scene
    scene.addItem(new QGraphicsPixmapItem(board_image_scaled));

    // get all stone positions for each color and add them on the right position to the scene
    auto black_stones = game_board->All(SG_BLACK);
    for (auto iter = SgSetIterator(black_stones); iter; ++iter) {
        auto point = *iter;

        // Reducing by -1 because board starts at 1,1
        auto col = SgPointUtil::Col(point) - 1;
        auto row = SgPointUtil::Row(point) - 1;

        //Vertically mirroring stones
        row = board_size - row - 1;

        QGraphicsPixmapItem* black_stone_item = new QGraphicsPixmapItem(black_stone_image_scaled);
        black_stone_item->setPos(cell_width * scale_x * col, cell_height * scale_y * row);
        black_stone_item->setOffset(cell_width * scale_x - black_stone_image_scaled.width()/2, cell_height * scale_y - black_stone_image_scaled.height()/2);
        scene.addItem(black_stone_item);
    }

    auto white_stones = game_board->All(SG_WHITE);
    for (auto iter = SgSetIterator(white_stones); iter; ++iter) {
        auto point = *iter;

        // Reducing by -1 because board starts at 1,1
        auto col = SgPointUtil::Col(point) - 1;
        auto row = SgPointUtil::Row(point) - 1;

        //Vertically mirroring stones
        row = board_size - row - 1;

        QGraphicsPixmapItem* black_stone_item = new QGraphicsPixmapItem(white_stone_image_scaled);
        black_stone_item->setPos(cell_width * scale_x * col, cell_height * scale_y * row);
        black_stone_item->setOffset(cell_width * scale_x - white_stone_image_scaled.width()/2, cell_height * scale_y - black_stone_image_scaled.height()/2);
        scene.addItem(black_stone_item);
    }

    // Stone that could be placed on board when user chooses to
    if (this->virtual_game_mode){
        this->ghost_stone = new QGraphicsEllipseItem(QRectF());
        ghost_stone->setRect(selection_ellipse);
        QBrush ghost_brush = game_board->ToPlay() == SG_BLACK ?
                            QBrush(Qt::GlobalColor::black):
                            QBrush(Qt::GlobalColor::white);

        this->ghost_stone->setOpacity(0.5);
        this->ghost_stone->setBrush(ghost_brush);
        this->scene.addItem(this->ghost_stone);
    }
    this->setScene(&scene);

    setting_stone_valid = true;
}

void VirtualView::resizeVirtualView(){
    this->resize(this->parentWidget()->size());
    this->fitInView(scene.sceneRect());
}

//SLOTS
void VirtualView::slot_setVirtualGameMode(bool checked){
    this->virtual_game_mode = checked;
    if (!checked && scene.isActive())
        scene.removeItem(ghost_stone);
}

void VirtualView::mousePressEvent(QMouseEvent* event){
    if (!virtual_game_mode)
        return;

    if (event->button() == Qt::LeftButton && setting_stone_valid){
        // the mouse_hover_coord is calculated starting from upper left corner
        // game board starts at left bottom corner -> mirror vertically
        int ycoord = board_size - mouse_hover_coord.y() + 1;
        emit signal_virtualViewplayMove(mouse_hover_coord.x(), ycoord);
        setting_stone_valid = false;
    }
}

void VirtualView::mouseMoveEvent(QMouseEvent* event){
    if (!virtual_game_mode)
        return;

    int pic_boarder_x = 60, pic_boarder_y = 55, board_pix;

    switch(this->board_size){
    case 9:
        board_pix = this->board_image_size9.size().width();
        break;
    case 13:
        board_pix = this->board_image_size13.size().width();
        break;
    case 19:
        board_pix = this->board_image_size19.size().width();
        break;
    default:
        return;
        break;
    }

    // calculate the scale of picture in viewport
    qreal scale_x = scene.sceneRect().size().width() * qreal(1.0)/board_pix;
    qreal scale_y = scene.sceneRect().size().height() * qreal(1.0)/board_pix;

    // getting transformation of scene (fitInView() scales the scene!)
    qreal transform_x = qreal(1.0) / this->transform().m11();
    qreal transform_y = qreal(1.0) / this->transform().m22();

    // mapping mousecoordinates to gameboard coordinates (example: x=0,2515, y=2,7622)
    qreal xCoordAccurate = (event->pos().x() * transform_x - pic_boarder_x * scale_x) / (this->cell_width * scale_x);
    qreal yCoordAccurate = (event->pos().y() * transform_y - pic_boarder_y * scale_y) / (this->cell_height * scale_y);

    // Rounding half up  (example: x=0, y=3)
    int board_x_coord = static_cast<int>(xCoordAccurate);
    int board_y_coord = static_cast<int>(yCoordAccurate);
    board_x_coord = xCoordAccurate - board_x_coord < 0.5f ? board_x_coord : board_x_coord + 1;
    board_y_coord = yCoordAccurate - board_y_coord < 0.5f ? board_y_coord : board_y_coord + 1;

    // Until now we calculated from 0,0. Game starts counting at 1,1
    QPoint new_mouse_hover_coord = QPoint(board_x_coord + 1,board_y_coord + 1);

    // If mouse hover coordinates differ -> move ellipse to new coordinates
    if (new_mouse_hover_coord != mouse_hover_coord
        && board_x_coord < board_size && board_y_coord < board_size){

        // calculate exact position of where to draw new ellipse
        qreal ellipse_xPos = (pic_boarder_x * scale_x) + (board_x_coord * this->cell_width * scale_x) - (this->cell_width * scale_x)/2.0f;
        qreal ellipse_yPos = (pic_boarder_y * scale_y) + (board_y_coord * this->cell_height * scale_y) - (this->cell_height * scale_y)/2.0f;

        QRectF new_selection_ellipse = QRectF(ellipse_xPos, ellipse_yPos, this->cell_width * scale_x, this->cell_height * scale_y);
        ghost_stone->setRect(new_selection_ellipse);
        selection_ellipse = new_selection_ellipse;

        // save new mouse hover coordinates
        mouse_hover_coord = new_mouse_hover_coord;
    }
}<commit_msg>fixes #140 Initialized with nullptr to test against that when trying to access "ghost_stone"<commit_after>#include "virtualview.hpp"

#include <QGLBuilder>
#include <QGLSceneNode>
#include <QGLAbstractScene>
#include <QMessageBox>
#include <QGraphicsPixmapItem>
#include <QtGui\QMouseEvent>

#include <GoBoard.h>

VirtualView::VirtualView(QWidget *parent){
    this->setParent(parent);

    this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    this->resize(parent->size());

    this->setMouseTracking(true);
    this->setting_stone_valid = false;

    // directories of the images
    QString texture_path = "res/textures/";
    QString board_directory_size9 = QString(texture_path + "go_board_" + QString::number(9)+".png");
    QString board_directory_size13 = QString(texture_path + "go_board_" + QString::number(13)+".png");
    QString board_directory_size19 = QString(texture_path + "go_board_" + QString::number(19)+".png");
    QString black_stone_directory = QString(texture_path + "black_stone.png");
    QString white_stone_directory = QString(texture_path + "white_stone.png");

    // loads the images and checks if the image could loaded
    board_image_size9 = QImage(board_directory_size9);
    board_image_size13 = QImage(board_directory_size13);
    board_image_size19 = QImage(board_directory_size19);
    black_stone_image = QImage(black_stone_directory);
    white_stone_image = QImage(white_stone_directory);

    // initialize with nullptr to be able to test against that
    ghost_stone = nullptr;
}
VirtualView::~VirtualView(){
}

void VirtualView::createAndSetScene(QSize size, const GoBoard * game_board)
{
    if (game_board == nullptr)
        return;

    this->resize(size);

    scene.clear();
    scene.setSceneRect(0,0, size.width(), size.height());
    fitInView(this->sceneRect());

    // loads the board size and checks if its a valid size
    board_size = game_board->Size();

    QImage board_image;

    switch(board_size){
    case 9:
        board_image = board_image_size9;
        break;
    case 13:
        board_image = board_image_size13;
        break;
    case 19:
        board_image = board_image_size19;
        break;
    default:
        QMessageBox::warning(this, "board size error", "invalid size of the board!");
    }

    if (board_image.isNull())
        QMessageBox::warning(this, "file loading error", "could not load board image!");
    if (black_stone_image.isNull())
        QMessageBox::warning(this, "file loading error", "could not load black stone image!");
    if (white_stone_image.isNull())
        QMessageBox::warning(this, "file loading error", "could not laod white stone image!");

    // scale_x and scale_y are the scaling factors of the virtual board
    float scale_x = size.width() / float(board_image.width());
    float scale_y = size.height() / float(board_image.height());

    cell_width = static_cast<qreal>(board_image.width()) / (board_size+1);
    cell_height = static_cast<qreal>(board_image.height()) / (board_size+1);

    // scale the images to the right size
    QPixmap board_image_scaled = QPixmap::fromImage(board_image);
    board_image_scaled = board_image_scaled.scaled(size.width(),size.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    QPixmap black_stone_image_scaled = QPixmap::fromImage(black_stone_image);
    black_stone_image_scaled = black_stone_image_scaled.scaled(black_stone_image.width()*scale_x, black_stone_image.height()*scale_y, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    QPixmap white_stone_image_scaled = QPixmap::fromImage(white_stone_image);
    white_stone_image_scaled = white_stone_image_scaled.scaled(white_stone_image.width()*scale_x, white_stone_image.height()*scale_y, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    if (board_image_scaled.isNull())
        QMessageBox::warning(this, "image scale error", "could not scale board!");
    if (black_stone_image_scaled.isNull())
        QMessageBox::warning(this, "image scale error", "could not scale black stone!");
    if (white_stone_image_scaled.isNull())
        QMessageBox::warning(this, "image scale error", "could not scale white stone!");

    // add the board image to the scene
    scene.addItem(new QGraphicsPixmapItem(board_image_scaled));

    // get all stone positions for each color and add them on the right position to the scene
    auto black_stones = game_board->All(SG_BLACK);
    for (auto iter = SgSetIterator(black_stones); iter; ++iter) {
        auto point = *iter;

        // Reducing by -1 because board starts at 1,1
        auto col = SgPointUtil::Col(point) - 1;
        auto row = SgPointUtil::Row(point) - 1;

        //Vertically mirroring stones
        row = board_size - row - 1;

        QGraphicsPixmapItem* black_stone_item = new QGraphicsPixmapItem(black_stone_image_scaled);
        black_stone_item->setPos(cell_width * scale_x * col, cell_height * scale_y * row);
        black_stone_item->setOffset(cell_width * scale_x - black_stone_image_scaled.width()/2, cell_height * scale_y - black_stone_image_scaled.height()/2);
        scene.addItem(black_stone_item);
    }

    auto white_stones = game_board->All(SG_WHITE);
    for (auto iter = SgSetIterator(white_stones); iter; ++iter) {
        auto point = *iter;

        // Reducing by -1 because board starts at 1,1
        auto col = SgPointUtil::Col(point) - 1;
        auto row = SgPointUtil::Row(point) - 1;

        //Vertically mirroring stones
        row = board_size - row - 1;

        QGraphicsPixmapItem* black_stone_item = new QGraphicsPixmapItem(white_stone_image_scaled);
        black_stone_item->setPos(cell_width * scale_x * col, cell_height * scale_y * row);
        black_stone_item->setOffset(cell_width * scale_x - white_stone_image_scaled.width()/2, cell_height * scale_y - black_stone_image_scaled.height()/2);
        scene.addItem(black_stone_item);
    }

    // Stone that could be placed on board when user chooses to
    if (this->virtual_game_mode){
        if (ghost_stone == nullptr)
            this->ghost_stone = new QGraphicsEllipseItem(QRectF());

        ghost_stone->setRect(selection_ellipse);
        QBrush ghost_brush = game_board->ToPlay() == SG_BLACK ?
                            QBrush(Qt::GlobalColor::black):
                            QBrush(Qt::GlobalColor::white);

        this->ghost_stone->setOpacity(0.5);
        this->ghost_stone->setBrush(ghost_brush);
        this->scene.addItem(this->ghost_stone);
    }
    this->setScene(&scene);

    setting_stone_valid = true;
}

void VirtualView::resizeVirtualView(){
    this->resize(this->parentWidget()->size());
    this->fitInView(scene.sceneRect());
}

//SLOTS
void VirtualView::slot_setVirtualGameMode(bool checked){
    this->virtual_game_mode = checked;
    if (!checked && scene.isActive())
        scene.removeItem(ghost_stone);
}

void VirtualView::mousePressEvent(QMouseEvent* event){
    if (!virtual_game_mode)
        return;

    if (event->button() == Qt::LeftButton && setting_stone_valid){
        // the mouse_hover_coord is calculated starting from upper left corner
        // game board starts at left bottom corner -> mirror vertically
        int ycoord = board_size - mouse_hover_coord.y() + 1;
        emit signal_virtualViewplayMove(mouse_hover_coord.x(), ycoord);
        setting_stone_valid = false;
    }
}

void VirtualView::mouseMoveEvent(QMouseEvent* event){
    if (!virtual_game_mode)
        return;

    int pic_boarder_x = 60, pic_boarder_y = 55, board_pix;

    switch(this->board_size){
    case 9:
        board_pix = this->board_image_size9.size().width();
        break;
    case 13:
        board_pix = this->board_image_size13.size().width();
        break;
    case 19:
        board_pix = this->board_image_size19.size().width();
        break;
    default:
        return;
        break;
    }

    // calculate the scale of picture in viewport
    qreal scale_x = scene.sceneRect().size().width() * qreal(1.0)/board_pix;
    qreal scale_y = scene.sceneRect().size().height() * qreal(1.0)/board_pix;

    // getting transformation of scene (fitInView() scales the scene!)
    qreal transform_x = qreal(1.0) / this->transform().m11();
    qreal transform_y = qreal(1.0) / this->transform().m22();

    // mapping mousecoordinates to gameboard coordinates (example: x=0,2515, y=2,7622)
    qreal xCoordAccurate = (event->pos().x() * transform_x - pic_boarder_x * scale_x) / (this->cell_width * scale_x);
    qreal yCoordAccurate = (event->pos().y() * transform_y - pic_boarder_y * scale_y) / (this->cell_height * scale_y);

    // Rounding half up  (example: x=0, y=3)
    int board_x_coord = static_cast<int>(xCoordAccurate);
    int board_y_coord = static_cast<int>(yCoordAccurate);
    board_x_coord = xCoordAccurate - board_x_coord < 0.5f ? board_x_coord : board_x_coord + 1;
    board_y_coord = yCoordAccurate - board_y_coord < 0.5f ? board_y_coord : board_y_coord + 1;

    // Until now we calculated from 0,0. Game starts counting at 1,1
    QPoint new_mouse_hover_coord = QPoint(board_x_coord + 1,board_y_coord + 1);

    // If mouse hover coordinates differ -> move ellipse to new coordinates
    if (new_mouse_hover_coord != mouse_hover_coord
        && board_x_coord < board_size && board_y_coord < board_size){

        // calculate exact position of where to draw new ellipse
        qreal ellipse_xPos = (pic_boarder_x * scale_x) + (board_x_coord * this->cell_width * scale_x) - (this->cell_width * scale_x)/2.0f;
        qreal ellipse_yPos = (pic_boarder_y * scale_y) + (board_y_coord * this->cell_height * scale_y) - (this->cell_height * scale_y)/2.0f;

        QRectF new_selection_ellipse = QRectF(ellipse_xPos, ellipse_yPos, this->cell_width * scale_x, this->cell_height * scale_y);
        if (ghost_stone == nullptr)
            this->ghost_stone = new QGraphicsEllipseItem(QRectF());
        ghost_stone->setRect(new_selection_ellipse);
        selection_ellipse = new_selection_ellipse;

        // save new mouse hover coordinates
        mouse_hover_coord = new_mouse_hover_coord;
    }
}<|endoftext|>