diff --git a/.gitignore b/.gitignore index fbf0a47..8fd1dc7 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,7 @@ # Build directories /.gradle -/build* +/build/ !build.gradle /native /arm diff --git a/.gitreview b/.gitreview deleted file mode 100644 index 0aa481b..0000000 --- a/.gitreview +++ /dev/null @@ -1,5 +0,0 @@ -[gerrit] -host=usfirst.collab.net -port=29418 -project=ntcore -defaultbranch=master \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 3cd1b41..cc60cf2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ matrix: sudo: required - os: osx osx_image: xcode8 - env: WPILIB_FLAGS=-PskipArm addons: apt: @@ -19,10 +18,10 @@ before_install: - .travis-scripts/install.sh install: - - ./gradlew assemble $WPILIB_FLAGS + - ./gradlew build -PbuildAll script: - - ./gradlew build $WPILIB_FLAGS + - ./gradlew build -PbuildAll before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 7ccb6fb..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,112 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(ntcore) - -if (MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DNOMINMAX /D_SCL_SECURE_NO_WARNINGS /D_WINSOCK_DEPRECATED_NO_WARNINGS") -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++1y -Wformat=2 -Wall -Wextra -Werror -pedantic -Wno-unused-parameter") -endif() - -# This must be a macro(), as inside a function string() can only -# update variables in the function scope. -macro(fix_default_compiler_settings_) - if (MSVC) - # For MSVC, CMake sets certain flags to defaults we want to override. - # This replacement code is taken from sample in the CMake Wiki at - # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace. - foreach (flag_var - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt) - # When Google Test is built as a shared library, it should also use - # shared runtime libraries. Otherwise, it may end up with multiple - # copies of runtime library data in different modules, resulting in - # hard-to-find crashes. When it is built as a static library, it is - # preferable to use CRT as static libraries, as we don't have to rely - # on CRT DLLs being available. CMake always defaults to using shared - # CRT libraries, so we override that default here. - string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}") - endif() - endforeach() - endif() -endmacro() -fix_default_compiler_settings_() - -file(GLOB_RECURSE SRC_FILES src/*.cpp) -include_directories(include src wpiutil/include) - -# Java bindings -if (NOT WITHOUT_JAVA) - find_package(Java) - find_package(JNI) - include(UseJava) - set(CMAKE_JAVA_COMPILE_FLAGS "-Xlint:unchecked") - - include_directories(${JNI_INCLUDE_DIRS}) - list(APPEND SRC_FILES java/lib/NetworkTablesJNI.cpp) - - file(GLOB_RECURSE JAVA_SOURCES java/src/*.java) - set(CMAKE_JNI_TARGET true) - add_jar(ntcore_jar ${JAVA_SOURCES} OUTPUT_NAME ntcore) - - # Generate JNI headers - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/edu_wpi_first_wpilibj_networktables_NetworkTablesJNI.h" - DEPENDS ntcore_jar java/src/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java - COMMAND "${Java_JAVAH_EXECUTABLE}" - -jni - -o "${CMAKE_CURRENT_BINARY_DIR}/edu_wpi_first_wpilibj_networktables_NetworkTablesJNI.h" - -classpath "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/ntcore_jar.dir/" - edu.wpi.first.wpilibj.networktables.NetworkTablesJNI - ) - include_directories("${CMAKE_CURRENT_BINARY_DIR}") - set_source_files_properties( - java/lib/NetworkTablesJNI.cpp - OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/edu_wpi_first_wpilibj_networktables_NetworkTablesJNI.h" - ) - - #add_subdirectory(java/test) -endif() - -if (WIN32) - if (NOT WITHOUT_JAVA) - add_library(ntcore SHARED ${SRC_FILES} ntcore-jni.def) - else() - add_library(ntcore SHARED ${SRC_FILES} ntcore.def) - endif() -else() - add_library(ntcore SHARED ${SRC_FILES}) -endif() -set_target_properties(ntcore PROPERTIES VERSION 1.0.0 SOVERSION 1) -target_link_libraries(ntcore wpiutil) -if (WIN32) - add_library(ntcore_static STATIC ${SRC_FILES}) - target_link_libraries(ntcore_static wpiutil) - target_link_libraries(ntcore ws2_32) - target_link_libraries(ntcore_static ws2_32) -endif() -INSTALL(TARGETS ntcore - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib COMPONENT lib) -INSTALL(DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT headers) - -file(GLOB_RECURSE WPIUTIL_SRC_FILES wpiutil/src/*.cpp) -add_library(wpiutil STATIC ${WPIUTIL_SRC_FILES}) -INSTALL(TARGETS wpiutil - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib COMPONENT lib) -INSTALL(DIRECTORY wpiutil/include DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT headers) - -# We need thread support -find_package(Threads REQUIRED) - -if (NOT WITHOUT_TESTS) - enable_testing() - - add_subdirectory(gmock) - include_directories("gmock/include") - include_directories("gmock/gtest/include") - add_subdirectory(test) -endif() diff --git a/appveyor.yml b/appveyor.yml index f89348a..713c47d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,27 +1,26 @@ -version: "{branch} {build}" - -image: -- Visual Studio 2015 -- Visual Studio 2013 - -build: - verbosity: detailed - -build_script: - - gradlew.bat assemble --info -PskipArm - -test_script: -- cmd: >- - SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0 - - gradlew.bat check --info -PskipArm - - SET JAVA_HOME=C:\Program Files (x86)\Java\jdk1.8.0 - - gradlew.bat check --info -PskipArm - -cache: - - C:\Users\appveyor\.gradle - -matrix: - fast_finish: true +version: "{branch} {build}" + +image: +- Visual Studio 2015 + +build: + verbosity: detailed + +build_script: + - gradlew.bat assemble --info -PbuildAll + +test_script: +- cmd: >- + SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0 + + gradlew.bat check --info -PbuildAll + + SET JAVA_HOME=C:\Program Files (x86)\Java\jdk1.8.0 + + gradlew.bat check --info -PbuildAll + +cache: + - C:\Users\appveyor\.gradle + +matrix: + fast_finish: true diff --git a/build.gradle b/build.gradle index 1d179b2..ce57a8e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,74 +1,201 @@ +import edu.wpi.first.nativeutils.NativeUtils +import org.gradle.api.file.FileCollection import org.gradle.internal.os.OperatingSystem +import edu.wpi.first.nativeutils.tasks.JNIHeaders buildscript { repositories { + mavenLocal() maven { url "https://plugins.gradle.org/m2/" } } dependencies { - classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.8' + classpath 'gradle.plugin.edu.wpi.first:native-utils:1.2.9' classpath 'gradle.plugin.edu.wpi.first.wpilib.versioning:wpilib-version-plugin:1.6' } } -ext.buildArm = !project.hasProperty('skipArm') -ext.includeJava = !project.hasProperty('skipJava') +repositories { + mavenCentral() +} -if (hasProperty('makeDesktop')) { - println 'Making desktop classifier jar. NOTE: This desktop version should only be used for local testing.' + - 'It will only support the current platform, and will override fetching the latest development version from' + - ' the maven repo until you manually delete it!' +ext.getClassifier = { binary-> + return NativeUtils.getClassifier(binary) } -ext.getPlatformPath = { binary -> - if (binary.targetPlatform.architecture.arm) { - return 'Linux/arm' - } else if (binary.targetPlatform.operatingSystem.linux) { - if (binary.targetPlatform.architecture.amd64) { - return 'Linux/amd64' - } else { - return 'Linux/i386' - } - } else if (binary.targetPlatform.operatingSystem.windows) { - if (binary.targetPlatform.architecture.amd64) { - return 'Windows/amd64' - } else { - return 'Windows/' + binary.targetPlatform.architecture.name - } - } else if (binary.targetPlatform.operatingSystem.macOsX) { - if (binary.targetPlatform.architecture.amd64) { - return 'Mac OS X/x86_64' - } else { - return 'Mac OS X/' + binary.targetPlatform.architecture.name - } - } else { - return binary.targetPlatform.operatingSystem.name + '/' + binary.targetPlatform.architecture.name - } +ext.getPlatformPath = { binary-> + return NativeUtils.getPlatformPath(binary) } -ext.setupDefines = { project, binaries -> - binaries.all { - if (project.hasProperty('debug')) { - project.setupDebugDefines(cppCompiler, linker) - } else { - project.setupReleaseDefines(cppCompiler, linker) - } +ext.getJNIHeadersClass = { + return JNIHeaders +} + +apply plugin: 'cpp' +apply plugin: 'google-test' +apply plugin: 'visual-studio' +apply plugin: 'edu.wpi.first.NativeUtils' +apply plugin: 'java' + +apply from: 'config.gradle' + +if (project.hasProperty('onlyAthena')) { + test.enabled = false +} + +task nativeTestFilesJar(type: Jar) { + destinationDir = project.buildDir + classifier = "nativeTestFiles" + + project.model { + binaries { + withType(SharedLibraryBinarySpec) { binary -> + if (binary.component.name == 'ntcoreJNI') { + from(binary.sharedLibraryFile) { + into NativeUtils.getPlatformPath(binary) + } + } + } + } } } -apply from: "ntcore.gradle" -apply from: "wpiutil.gradle" +test.dependsOn nativeTestFilesJar + +dependencies { + compile 'edu.wpi.first.wpiutil:wpiutil-java:+' + runtime 'edu.wpi.first.wpiutil:wpiutil-java:+' + testCompile 'junit:junit:4.12' + testRuntime files(project(':').nativeTestFilesJar.archivePath) +} -// Empty task for build so that ntcoreSourceZip and wpiutilSourceZip will be -// built when running ./gradlew build -task build -build.dependsOn ntcoreSourceZip -build.dependsOn wpiutilSourceZip +model { + jniConfigs { + ntcore(JNIConfig) { + jniDefinitionClasses = [ "edu.wpi.first.wpilibj.networktables.NetworkTablesJNI" ] + jniArmHeaderLocations = [ all: file("${rootDir}/src/arm-linux-jni") ] + sourceSets = [ project.sourceSets.main ] + } + ntcoreJNI(JNIConfig) { + jniDefinitionClasses = [ "edu.wpi.first.wpilibj.networktables.NetworkTablesJNI" ] + jniArmHeaderLocations = [ all: file("${rootDir}/src/arm-linux-jni") ] + sourceSets = [ project.sourceSets.main ] + } + } + exportsConfigs { + ntcore(ExportsConfig) { + x86ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure', + '_CT??_R0?AVbad_cast', + '_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure', + '_TI5?AVfailure' ] + x64ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure', + '_CT??_R0?AVbad_cast', + '_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure', + '_TI5?AVfailure' ] + } + ntcoreJNI(ExportsConfig) { + x86SymbolFilter = { symbols-> + def retList = [] + symbols.each { symbol-> + if (symbol.startsWith('NT_') || symbol.startsWith('Java_') || symbol.startsWith('JNI_')) { + retList << symbol + } + } + return retList + } + x64SymbolFilter = { symbols-> + def retList = [] + symbols.each { symbol-> + if (symbol.startsWith('NT_') || symbol.startsWith('Java_') || symbol.startsWith('JNI_')) { + retList << symbol + } + } + return retList + } + } + } + dependencyConfigs { + wpiutil(DependencyConfig) { + groupId = 'edu.wpi.first.wpiutil' + artifactId = 'wpiutil-cpp' + headerClassifier = 'headers' + ext = 'zip' + version = '+' + sharedConfigs = [ ntcore: [], + ntcoreExe: [], + ntcoreTestingBaseTest: [] ] + staticConfigs = [ ntcoreJNI: [] ] + } + } + components { + ntcore(NativeLibrarySpec) { + sources { + cpp { + source { + srcDirs 'src/main/native/cpp' + include '**/*.cpp' + } + exportedHeaders { + srcDirs 'src/main/native/include' + } + } + } + } + ntcoreJNI(NativeLibrarySpec) { + baseName = 'ntcore' + sources { + cpp { + source { + srcDirs 'src/main/native/cpp' + include '**/*.cpp' + } + exportedHeaders { + srcDirs 'src/main/native/include' + } + } + } + } + if (!project.hasProperty('skipTestExe')) { + ntcoreExe(NativeExecutableSpec) { + sources { + cpp { + lib library: "ntcore" + } + } + } + } + ntcoreTestingBase(NativeLibrarySpec) { } + } + testSuites { + ntcoreTestingBaseTest { + sources { + cpp.source.srcDir 'src/test/native/cpp' + cpp.exportedHeaders.srcDir 'src/test/native/include' + } + } + } + binaries { + withType(StaticLibraryBinarySpec) { + if (it.component.name == 'ntcoreJNI') { + it.buildable = false + } + } + withType(GoogleTestTestSuiteBinarySpec) { + if (it.component.testedComponent.name.contains('TestingBase') && !project.hasProperty('onlyAthena')) { + lib project: ':gmock', library: 'gmock', linkage: 'static' + lib library: 'ntcore', linkage: 'shared' + NativeUtils.setPlatformSpecificIncludeFlag("${rootDir}/src/main/native/cpp".toString(), cppCompiler) + } else { + it.buildable = false + } + } + } +} apply from: 'publish.gradle' task wrapper(type: Wrapper) { - gradleVersion = '3.3' + gradleVersion = '4.0.2' } diff --git a/config.gradle b/config.gradle new file mode 100644 index 0000000..1ac9119 --- /dev/null +++ b/config.gradle @@ -0,0 +1,226 @@ +import edu.wpi.first.nativeutils.* +import org.gradle.internal.os.OperatingSystem + +def windowsCompilerArgs = ['/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS', + '/Zi', '/FS', '/Zc:inline', '/MT'] +def windowsReleaseCompilerArgs = ['/O2'] +def windowsLinkerArgs = [ '/DEBUG:FULL' ] +def windowsReleaseLinkerArgs = [ '/OPT:REF', '/OPT:ICF' ] + +def linuxCompilerArgs = ['-std=c++11', '-Wformat=2', '-Wall', '-Wextra', '-Werror', '-pedantic', '-Wno-psabi', '-g', + '-Wno-unused-parameter', '-fPIC', '-rdynamic', '-Wno-error=deprecated-declarations', '-pthread'] +def linuxLinkerArgs = ['-rdynamic', '-pthread'] +def linuxReleaseCompilerArgs = ['-O2'] +def linuxDebugCompilerArgs = ['-O0'] +def linux32BitArg = '-m32' + +def macCompilerArgs = ['-std=c++11', '-Wall', '-Wextra', '-Werror', '-pedantic-errors', '-fPIC', '-g', + '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-Wno-unused-private-field'] +def macReleaseCompilerArgs = ['-O2'] +def macDebugCompilerArgs = ['-O0'] +def mac32BitArg = '-m32' + +def buildAll = project.hasProperty('buildAll') + +def windows64PlatformDetect = { + def arch = System.getProperty("os.arch") + def isWin = OperatingSystem.current().isWindows() + if (buildAll) { + return isWin + } else { + return isWin && arch == 'amd64' + } +} + +def windows32PlatformDetect = { + def arch = System.getProperty("os.arch") + def isWin = OperatingSystem.current().isWindows() + if (buildAll) { + return isWin + } else { + return isWin && arch == 'x86' + } +} + +def linux32IntelPlatformDetect = { + def arch = System.getProperty("os.arch") + def isLinux = OperatingSystem.current().isLinux() + def isIntel = (arch == 'amd64' || arch == 'i386') + if (buildAll) { + return isLinux && isIntel + } else { + return isLinux && arch == 'i386' + } +} + +def linux64IntelPlatformDetect = { + def arch = System.getProperty("os.arch") + def isLinux = OperatingSystem.current().isLinux() + def isIntel = (arch == 'amd64' || arch == 'i386') + if (buildAll) { + return isLinux && isIntel + } else { + return isLinux && arch == 'amd64' + } +} + +def linuxArmPlatformDetect = { + def arch = System.getProperty("os.arch") + def isIntel = (arch == 'amd64' || arch == 'i386') + return OperatingSystem.current().isLinux() && !isIntel +} + +def mac64PlatformDetect = { + def arch = System.getProperty("os.arch") + def isMac = OperatingSystem.current().isMacOsX() + if (buildAll) { + return isMac + } else { + return isMac && arch == 'x86_64' + } +} + +def mac32PlatformDetect = { + def arch = System.getProperty("os.arch") + def isMac = OperatingSystem.current().isMacOsX() + if (buildAll) { + return isMac + } else { + return isMac && arch == 'x86' + } +} + +if (!project.hasProperty('skipAthena')) { + model { + buildConfigs { + roboRio(CrossBuildConfig) { + architecture = 'athena' + operatingSystem = 'linux' + toolChainPrefix = 'arm-frc-linux-gnueabi-' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + releaseStripBinaries = true + compilerFamily = 'Gcc' + exclude << 'gmock' + exclude << 'wpiutilTestingBase' + } + } + } +} + +if (!project.hasProperty('onlyAthena')) { + model { + buildConfigs { + winX86(BuildConfig) { + architecture = 'x86' + operatingSystem = 'windows' + compilerArgs = windowsCompilerArgs + linkerArgs = windowsLinkerArgs + releaseCompilerArgs = windowsReleaseCompilerArgs + releaseLinkerArgs = windowsReleaseLinkerArgs + compilerFamily = 'VisualCpp' + detectPlatform = windows32PlatformDetect + } + winX64(BuildConfig) { + architecture = 'x86-64' + operatingSystem = 'windows' + compilerArgs = windowsCompilerArgs + linkerArgs = windowsLinkerArgs + releaseCompilerArgs = windowsReleaseCompilerArgs + releaseLinkerArgs = windowsReleaseLinkerArgs + compilerFamily = 'VisualCpp' + detectPlatform = windows64PlatformDetect + } + linuxX86(BuildConfig) { + architecture = 'x86' + operatingSystem = 'linux' + compilerArgs = linuxCompilerArgs + compilerArgs << linux32BitArg + linkerArgs = linuxLinkerArgs + linkerArgs << linux32BitArg + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + compilerFamily = 'Gcc' + detectPlatform = linux32IntelPlatformDetect + } + linuxX64(BuildConfig) { + architecture = 'x86-64' + operatingSystem = 'linux' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + compilerFamily = 'Gcc' + detectPlatform = linux64IntelPlatformDetect + } + macX86(BuildConfig) { + architecture = 'x86' + operatingSystem = 'osx' + compilerArgs = macCompilerArgs + compilerArgs << mac32BitArg + linkerArgs << mac32BitArg + debugCompilerArgs = macDebugCompilerArgs + releaseCompilerArgs = macReleaseCompilerArgs + compilerFamily = 'Clang' + detectPlatform = mac32PlatformDetect + } + macX64(BuildConfig) { + architecture = 'x86-64' + operatingSystem = 'osx' + compilerArgs = macCompilerArgs + debugCompilerArgs = macDebugCompilerArgs + releaseCompilerArgs = macReleaseCompilerArgs + compilerFamily = 'Clang' + detectPlatform = mac64PlatformDetect + } + raspbian(CrossBuildConfig) { + architecture = 'raspbian' + operatingSystem = 'linux' + toolChainPrefix = 'arm-linux-gnueabihf-' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + skipByDefault = true + compilerFamily = 'Gcc' + exclude << 'gmock' + } + armhf(CrossBuildConfig) { + architecture = 'armhf' + operatingSystem = 'linux' + toolChainPrefix = 'arm-linux-gnueabihf-' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + skipByDefault = true + compilerFamily = 'Gcc' + exclude << 'gmock' + } + aarch(CrossBuildConfig) { + architecture = 'aarch' + operatingSystem = 'linux' + toolChainPrefix = 'aarch-linux-gnu-' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + skipByDefault = true + compilerFamily = 'Gcc' + exclude << 'gmock' + } + linuxArm(BuildConfig) { + architecture = 'arm' + operatingSystem = 'linux' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + compilerFamily = 'Gcc' + detectPlatform = linuxArmPlatformDetect + } + } + } +} diff --git a/gmock/build.gradle b/gmock/build.gradle index 809c55c..51ff139 100644 --- a/gmock/build.gradle +++ b/gmock/build.gradle @@ -1,49 +1,38 @@ import org.gradle.internal.os.OperatingSystem -apply plugin: 'cpp' -apply plugin: 'visual-studio' +if (!project.hasProperty('onlyAthena')) { + apply plugin: 'cpp' + apply plugin: 'visual-studio' + apply plugin: 'edu.wpi.first.NativeUtils' -// Apply the correct toolchain settings for the target platform -if (OperatingSystem.current().isLinux()) { - apply from: '../toolchains/linux.gradle' -} else if (OperatingSystem.current().isMacOsX()) { - apply from: '../toolchains/mac.gradle' -} else if (OperatingSystem.current().isWindows()) { - apply from: '../toolchains/windows.gradle' -} else { - throw new GradleException("ntcore does not support building on ${OperatingSystem.current().getFamilyName()}.") -} + ext.gmockProject = true -model { - platforms { - x86 { - architecture 'x86' - } - x64 { - architecture 'x86_64' - } - } - components { - gmock(NativeLibrarySpec) { - targetPlatform 'x86' - targetPlatform 'x64' - sources { - cpp { - source { - srcDirs = ['src', 'gtest/src'] - includes = ['*-all.cc'] + apply from: '../config.gradle' + + model { + components { + gmock(NativeLibrarySpec) { + sources { + cpp { + source { + srcDirs = ['src', 'gtest/src'] + includes = ['*-all.cc'] + } + exportedHeaders { + srcDirs = ['include', 'gtest/include', '.', 'gtest'] + includes = ['**/*.h', '**/*.cc'] + } } - exportedHeaders { - srcDirs = ['include', 'gtest/include', '.', 'gtest'] - includes = ['**/*.h', '**/*.cc'] + } + binaries.all { + if (toolChain in VisualCpp) { + cppCompiler.args '-D_UNICODE', '-DUNICODE', '-DWIN32', '-D_WIN32', '-DSTRICT', '-DWIN32_LEAN_AND_MEAN', '-D_HAS_EXCEPTIONS=1' + } else { + cppCompiler.args '-Wall', '-Wshadow', '-fexceptions', '-Wextra', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-pthread', '-fPIC' } } - } - binaries.all { - if (toolChain in VisualCpp) { - cppCompiler.args '-D_UNICODE', '-DUNICODE', '-DWIN32', '-D_WIN32', '-DSTRICT', '-DWIN32_LEAN_AND_MEAN', '-D_HAS_EXCEPTIONS=1' - } else { - cppCompiler.args '-Wall', '-Wshadow', '-fexceptions', '-Wextra', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-pthread', '-fPIC' + binaries.withType(SharedLibraryBinarySpec) { + buildable = false } } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a27e727..bd7feaa 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f1f921c..96b2d96 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Jan 04 18:53:29 PST 2017 +#Thu Aug 03 08:44:52 PDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.0.2-bin.zip diff --git a/gradlew b/gradlew index 4453cce..cccdd3d 100755 --- a/gradlew +++ b/gradlew @@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -155,7 +155,7 @@ if $cygwin ; then fi # Escape application args -save ( ) { +save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } diff --git a/java/java.gradle b/java/java.gradle deleted file mode 100644 index 2ca3bfc..0000000 --- a/java/java.gradle +++ /dev/null @@ -1,180 +0,0 @@ -import org.gradle.internal.os.OperatingSystem - -apply plugin: 'java' -apply plugin: 'net.ltgt.errorprone' - -repositories { - mavenCentral() -} - -configurations.errorprone { - resolutionStrategy.force 'com.google.errorprone:error_prone_core:2.0.9' -} - -def generatedJNIHeaderLoc = "${buildDir}/include" - -sourceSets { - main { - java { - srcDirs = ["${rootDir}/java/src"] - } - } -} - -jar { - description = 'Generates NetworkTables jar, with the JNI shared libraries embedded' - baseName = 'ntcore' - if (project.isArm && project.hasProperty('compilerPrefix') - && project.hasProperty('armSuffix')) { - classifier = "${buildPlatform}${project.armSuffix}" - } else { - classifier = "${buildPlatform}" - } - duplicatesStrategy = 'exclude' - - dependsOn { classes } - model { - binaries { - withType(SharedLibraryBinarySpec) { binary -> - // Only include the native file if not cross compiling to the roboRIO - if (!project.isArm || project.hasProperty('compilerPrefix')) - from(file(binary.sharedLibraryFile)) { - into getPlatformPath(binary) - } - } - } - } -} - -project.tasks.whenTaskAdded { task -> - if (isArm) { - if (task.name == 'ntcoreSharedLibrary') jar.dependsOn task - } else { - if (task.name == 'ntcoreX64SharedLibrary' || task.name == 'ntcoreX86SharedLibrary') - jar.dependsOn task - } -} - -task networktablesJavaSource(type: Jar, dependsOn: classes) { - description = 'Generates the source jar for NetworkTables java' - group = 'WPILib' - baseName = 'ntcore' - classifier = "sources" - duplicatesStrategy = 'exclude' - - from sourceSets.main.allJava -} - -task networktablesJavadoc(type: Jar, dependsOn: javadoc) { - description = 'Generates the javadoc jar for NetworkTables java' - group = 'WPILib' - baseName = 'ntcore' - classifier = "javadoc" - duplicatesStrategy = 'exclude' - - from javadoc.destinationDir -} - -build.dependsOn networktablesJavaSource -build.dependsOn networktablesJavadoc - -/** - * Generates the JNI headers - */ -task jniHeadersNetworkTables { - description = 'Generates JNI headers from edu.wpi.first.wpilibj.networktables.*' - group = 'WPILib' - def outputFolder = file(generatedJNIHeaderLoc) - inputs.files sourceSets.main.output - outputs.file outputFolder - doLast { - outputFolder.mkdirs() - exec { - executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah') - args '-d', outputFolder - args '-classpath', sourceSets.main.output.classesDir - args 'edu.wpi.first.wpilibj.networktables.NetworkTablesJNI' - } - } -} - -ext.getNativeJNISymbols = { - def symbolsList = [] - - jniHeadersNetworkTables.outputs.files.each { - FileTree tree = fileTree(dir: it) - tree.each { File file -> - file.eachLine { line -> - if (line.trim()) { - if (line.startsWith("JNIEXPORT ") && line.contains('JNICALL')) { - def (p1, p2) = line.split('JNICALL').collect { it.trim() } - // p2 is our JNI call - symbolsList << p2 - } - } - } - } - } - - return symbolsList -} - -clean { - delete generatedJNIHeaderLoc -} - -compileJava { - options.compilerArgs << '-Xlint:unchecked' -} - -javadoc { - options.addStringOption('Xdoclint:none', '-quiet') -} - -// This creates a lambda that the main build.gradle can access, which sets up the JNI includes for the -// target build platform. This lambda is exposed as a property in the main build.gradle. -ext.setupJniIncludes = { binaries -> - def platformSpecificIncludeFlag = { loc, cppCompiler -> - if (OperatingSystem.current().isWindows()) { - cppCompiler.args "/I$loc" - } else { - cppCompiler.args '-I', loc - } - } - binaries.all { - tasks.withType(CppCompile) { - if (buildPlatform == 'arm') { - cppCompiler.args '-I', file("${rootDir}/java/arm-linux").absolutePath - cppCompiler.args '-I', file("${rootDir}/java/arm-linux/linux").absolutePath - } else { - def jdkLocation = org.gradle.internal.jvm.Jvm.current().javaHome - platformSpecificIncludeFlag("${jdkLocation}/include", cppCompiler) - - if (targetPlatform.operatingSystem.macOsX) { - platformSpecificIncludeFlag("${jdkLocation}/include/darwin", cppCompiler) - } else if (targetPlatform.operatingSystem.linux) { - platformSpecificIncludeFlag("${jdkLocation}/include/linux", cppCompiler) - } else if (targetPlatform.operatingSystem.windows) { - platformSpecificIncludeFlag("${jdkLocation}/include/win32", cppCompiler) - } else if (targetPlatform.operatingSystem.freeBSD) { - platformSpecificIncludeFlag("${jdkLocation}/include/freebsd", cppCompiler) - } else if (file("$jdkLocation/include/darwin").exists()) { - // TODO: As of Gradle 2.8, targetPlatform.operatingSystem.macOsX returns false - // on El Capitan. We therefore manually test for the darwin folder and include it - // if it exists - platformSpecificIncludeFlag("${jdkLocation}/include/darwin", cppCompiler) - } - } - - jniHeadersNetworkTables.outputs.files.each { file -> - if (buildPlatform == 'arm') { - cppCompiler.args '-I', file.getPath() - } else { - platformSpecificIncludeFlag(file.getPath(), cppCompiler) - } - } - - dependsOn jniHeadersNetworkTables - } - } -} diff --git a/java/test/Client.java b/manualTests/java/Client.java similarity index 100% rename from java/test/Client.java rename to manualTests/java/Client.java diff --git a/java/test/Server.java b/manualTests/java/Server.java similarity index 100% rename from java/test/Server.java rename to manualTests/java/Server.java diff --git a/test/client.cpp b/manualTests/native/client.cpp similarity index 100% rename from test/client.cpp rename to manualTests/native/client.cpp diff --git a/test/rpc_local.cpp b/manualTests/native/rpc_local.cpp similarity index 100% rename from test/rpc_local.cpp rename to manualTests/native/rpc_local.cpp diff --git a/test/rpc_speed.cpp b/manualTests/native/rpc_speed.cpp similarity index 100% rename from test/rpc_speed.cpp rename to manualTests/native/rpc_speed.cpp diff --git a/test/server.cpp b/manualTests/native/server.cpp similarity index 100% rename from test/server.cpp rename to manualTests/native/server.cpp diff --git a/ntcore-jni.def b/ntcore-jni.def deleted file mode 100644 index b948984..0000000 --- a/ntcore-jni.def +++ /dev/null @@ -1,199 +0,0 @@ -LIBRARY NTCORE -EXPORTS -NT_GetEntryValue @1 -NT_SetEntryValue @2 -NT_SetEntryTypeValue @3 -NT_SetEntryFlags @4 -NT_GetEntryFlags @5 -NT_DeleteEntry @6 -NT_DeleteAllEntries @7 -NT_GetEntryInfo @8 -NT_Flush @9 -NT_AddEntryListener @10 -NT_RemoveEntryListener @11 -NT_AddConnectionListener @12 -NT_RemoveConnectionListener @13 -NT_SetNetworkIdentity @18 -NT_StartServer @19 -NT_StopServer @20 -NT_StartClient @21 -NT_StopClient @22 -NT_SetUpdateRate @23 -NT_GetConnections @24 -NT_SavePersistent @25 -NT_LoadPersistent @26 -NT_DisposeValue @27 -NT_InitValue @28 -NT_DisposeString @29 -NT_InitString @30 -NT_DisposeConnectionInfoArray @31 -NT_Now @32 -NT_SetLogger @33 -NT_CreateRpc @34 -NT_CreatePolledRpc @35 -NT_PollRpc @36 -NT_PostRpcResponse @37 -NT_CallRpc @38 -NT_GetRpcResult @39 -NT_PackRpcDefinition @40 -NT_UnpackRpcDefinition @41 -NT_PackRpcValues @42 -NT_UnpackRpcValues @43 -NT_DisposeRpcDefinition @44 -NT_DisposeRpcCallInfo @45 -NT_GetType @46 -NT_AllocateDoubleArray @47 -NT_AllocateBooleanArray @48 -NT_AllocateStringArray @49 -NT_FreeDoubleArray @51 -NT_FreeBooleanArray @52 -NT_FreeStringArray @53 -NT_GetValueType @54 -NT_GetValueBoolean @55 -NT_GetValueDouble @56 -NT_GetValueString @57 -NT_GetValueRaw @58 -NT_GetValueBooleanArray @59 -NT_GetValueDoubleArray @60 -NT_GetValueStringArray @61 -NT_GetEntryBoolean @62 -NT_GetEntryDouble @63 -NT_GetEntryString @64 -NT_GetEntryRaw @65 -NT_GetEntryBooleanArray @66 -NT_GetEntryDoubleArray @67 -NT_GetEntryStringArray @68 -NT_SetEntryDouble @69 -NT_SetEntryBoolean @70 -NT_SetEntryString @71 -NT_SetEntryRaw @72 -NT_SetEntryBooleanArray @73 -NT_SetEntryDoubleArray @74 -NT_SetEntryStringArray @75 -NT_DisposeEntryInfoArray @76 -NT_AllocateCharArray @77 -NT_FreeCharArray @78 -NT_NotifierDestroyed @79 -NT_StopRpcServer @80 -NT_StopNotifier @81 -NT_SetListenerOnStart @82 -NT_SetListenerOnExit @83 -NT_SetRpcServerOnStart @84 -NT_SetRpcServerOnExit @85 -NT_StartClientMulti @86 - -NT_SetDefaultEntryValue @87 -NT_SetDefaultEntryBoolean @88 -NT_SetDefaultEntryDouble @89 -NT_SetDefaultEntryString @90 -NT_SetDefaultEntryRaw @91 -NT_SetDefaultEntryBooleanArray @92 -NT_SetDefaultEntryDoubleArray @93 -NT_SetDefaultEntryStringArray @94 -NT_PollRpcTimeout @95 -NT_GetRpcResultTimeout @96 -NT_CancelBlockingRpcResult @97 - -NT_GetStringForTesting @98 -NT_GetEntryInfoForTesting @99 -NT_FreeEntryInfoForTesting @101 -NT_GetConnectionInfoForTesting @102 -NT_FreeConnectionInfoForTesting @103 -NT_GetValueBooleanForTesting @104 -NT_GetValueDoubleForTesting @105 -NT_GetValueStringForTesting @106 -NT_GetValueRawForTesting @107 -NT_GetValueBooleanArrayForTesting @108 -NT_GetValueDoubleArrayForTesting @109 -NT_GetValueStringArrayForTesting @110 -NT_GetRpcParamDefForTesting @111 -NT_FreeRpcParamDefForTesting @112 -NT_GetRpcResultsDefForTesting @113 -NT_FreeRpcResultsDefForTesting @114 -NT_GetRpcDefinitionForTesting @115 -NT_GetRpcCallInfoForTesting @116 - -NT_SetServer @117 -NT_SetServerMulti @118 -NT_StartDSClient @119 -NT_StopDSClient @120 -NT_StartClientNone @121 - -NT_GetNetworkMode @122 - -; JNI functions -JNI_OnLoad -JNI_OnUnload -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_containsKey -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getType -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putBoolean -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putDouble -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putString -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putRaw__Ljava_lang_String_2_3B -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putRaw__Ljava_lang_String_2Ljava_nio_ByteBuffer_2I -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putBooleanArray -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putDoubleArray -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_putStringArray -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutBoolean -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutDouble -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutString -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutRaw__Ljava_lang_String_2_3B -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutRaw__Ljava_lang_String_2Ljava_nio_ByteBuffer_2I -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutBooleanArray -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutDoubleArray -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_forcePutStringArray -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getValue__Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getBoolean__Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getDouble__Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getString__Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getRaw__Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getBooleanArray__Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getDoubleArray__Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getStringArray__Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getValue__Ljava_lang_String_2Ljava_lang_Object_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getBoolean__Ljava_lang_String_2Z -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getDouble__Ljava_lang_String_2D -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getString__Ljava_lang_String_2Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getRaw__Ljava_lang_String_2_3B -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getBooleanArray__Ljava_lang_String_2_3Z -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getDoubleArray__Ljava_lang_String_2_3D -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getStringArray__Ljava_lang_String_2_3Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setEntryFlags -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getEntryFlags -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_deleteEntry -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_deleteAllEntries -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getEntries -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_flush -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_addEntryListener -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_removeEntryListener -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_addConnectionListener -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_removeConnectionListener -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getRpc__Ljava_lang_String_2 -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getRpc__Ljava_lang_String_2_3B -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_callRpc__Ljava_lang_String_2_3B -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_callRpc__Ljava_lang_String_2Ljava_nio_ByteBuffer_2I -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setNetworkIdentity -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startServer -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_stopServer -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startClient__ -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startClient__Ljava_lang_String_2I -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startClient___3Ljava_lang_String_2_3I -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_stopClient -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setServer__Ljava_lang_String_2I -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setServer___3Ljava_lang_String_2_3I -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_startDSClient -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_stopDSClient -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setUpdateRate -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getConnections -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_savePersistent -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_loadPersistent -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_now -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setLogger -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultBoolean -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultDouble -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultString -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultRaw -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultBooleanArray -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultDoubleArray -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_setDefaultStringArray -Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_getNetworkMode diff --git a/ntcore.def b/ntcore.def deleted file mode 100644 index 0462af5..0000000 --- a/ntcore.def +++ /dev/null @@ -1,122 +0,0 @@ -LIBRARY NTCORE -EXPORTS -NT_GetEntryValue @1 -NT_SetEntryValue @2 -NT_SetEntryTypeValue @3 -NT_SetEntryFlags @4 -NT_GetEntryFlags @5 -NT_DeleteEntry @6 -NT_DeleteAllEntries @7 -NT_GetEntryInfo @8 -NT_Flush @9 -NT_AddEntryListener @10 -NT_RemoveEntryListener @11 -NT_AddConnectionListener @12 -NT_RemoveConnectionListener @13 -NT_SetNetworkIdentity @18 -NT_StartServer @19 -NT_StopServer @20 -NT_StartClient @21 -NT_StopClient @22 -NT_SetUpdateRate @23 -NT_GetConnections @24 -NT_SavePersistent @25 -NT_LoadPersistent @26 -NT_DisposeValue @27 -NT_InitValue @28 -NT_DisposeString @29 -NT_InitString @30 -NT_DisposeConnectionInfoArray @31 -NT_Now @32 -NT_SetLogger @33 -NT_CreateRpc @34 -NT_CreatePolledRpc @35 -NT_PollRpc @36 -NT_PostRpcResponse @37 -NT_CallRpc @38 -NT_GetRpcResult @39 -NT_PackRpcDefinition @40 -NT_UnpackRpcDefinition @41 -NT_PackRpcValues @42 -NT_UnpackRpcValues @43 -NT_DisposeRpcDefinition @44 -NT_DisposeRpcCallInfo @45 -NT_GetType @46 -NT_AllocateDoubleArray @47 -NT_AllocateBooleanArray @48 -NT_AllocateStringArray @49 -NT_FreeDoubleArray @51 -NT_FreeBooleanArray @52 -NT_FreeStringArray @53 -NT_GetValueType @54 -NT_GetValueBoolean @55 -NT_GetValueDouble @56 -NT_GetValueString @57 -NT_GetValueRaw @58 -NT_GetValueBooleanArray @59 -NT_GetValueDoubleArray @60 -NT_GetValueStringArray @61 -NT_GetEntryBoolean @62 -NT_GetEntryDouble @63 -NT_GetEntryString @64 -NT_GetEntryRaw @65 -NT_GetEntryBooleanArray @66 -NT_GetEntryDoubleArray @67 -NT_GetEntryStringArray @68 -NT_SetEntryDouble @69 -NT_SetEntryBoolean @70 -NT_SetEntryString @71 -NT_SetEntryRaw @72 -NT_SetEntryBooleanArray @73 -NT_SetEntryDoubleArray @74 -NT_SetEntryStringArray @75 -NT_DisposeEntryInfoArray @76 -NT_AllocateCharArray @77 -NT_FreeCharArray @78 -NT_NotifierDestroyed @79 -NT_StopRpcServer @80 -NT_StopNotifier @81 -NT_SetListenerOnStart @82 -NT_SetListenerOnExit @83 -NT_SetRpcServerOnStart @84 -NT_SetRpcServerOnExit @85 -NT_StartClientMulti @86 - -NT_SetDefaultEntryValue @87 -NT_SetDefaultEntryBoolean @88 -NT_SetDefaultEntryDouble @89 -NT_SetDefaultEntryString @90 -NT_SetDefaultEntryRaw @91 -NT_SetDefaultEntryBooleanArray @92 -NT_SetDefaultEntryDoubleArray @93 -NT_SetDefaultEntryStringArray @94 -NT_PollRpcTimeout @95 -NT_GetRpcResultTimeout @96 -NT_CancelBlockingRpcResult @97 - -NT_GetStringForTesting @98 -NT_GetEntryInfoForTesting @99 -NT_FreeEntryInfoForTesting @101 -NT_GetConnectionInfoForTesting @102 -NT_FreeConnectionInfoForTesting @103 -NT_GetValueBooleanForTesting @104 -NT_GetValueDoubleForTesting @105 -NT_GetValueStringForTesting @106 -NT_GetValueRawForTesting @107 -NT_GetValueBooleanArrayForTesting @108 -NT_GetValueDoubleArrayForTesting @109 -NT_GetValueStringArrayForTesting @110 -NT_GetRpcParamDefForTesting @111 -NT_FreeRpcParamDefForTesting @112 -NT_GetRpcResultsDefForTesting @113 -NT_FreeRpcResultsDefForTesting @114 -NT_GetRpcDefinitionForTesting @115 -NT_GetRpcCallInfoForTesting @116 - -NT_SetServer @117 -NT_SetServerMulti @118 -NT_StartDSClient @119 -NT_StopDSClient @120 -NT_StartClientNone @121 - -NT_GetNetworkMode @122 diff --git a/ntcore.gradle b/ntcore.gradle deleted file mode 100644 index 39fb71e..0000000 --- a/ntcore.gradle +++ /dev/null @@ -1,173 +0,0 @@ -def ntcoreSetupModel = { project -> - project.model { - components { - ntcore(NativeLibrarySpec) { - if (project.isArm) { - targetPlatform 'arm' - } else { - targetPlatform 'x86' - targetPlatform 'x64' - } - setupDefines(project, binaries) - - if (includeJava) { - project.setupJniIncludes(binaries) - project.checkNativeSymbols(project.getNativeJNISymbols) - binaries.all { - project.setupDef(linker, "${rootDir}/ntcore-jni.def") - } - } else { - binaries.all { - project.setupDef(linker, "${rootDir}/ntcore.def") - } - } - - sources { - cpp { - source { - srcDirs = ["${rootDir}/src"] - if (includeJava) { - srcDirs "${rootDir}/java/lib" - } - includes = ['**/*.cpp'] - } - exportedHeaders { - srcDirs = ["${rootDir}/include"] - if (includeJava) { - project.jniHeadersNetworkTables.outputs.files.each { file -> - srcDirs file.getPath() - } - } - includes = ['**/*.h'] - } - if (project.isArm && project.hasProperty('compilerPrefix')) { - lib project: ':arm:wpiutil', library: 'wpiutil', linkage: 'static' - } else if (project.isArm) { - // If roboRIO, link shared - lib project: ':arm:wpiutil', library: 'wpiutil', linkage: 'shared' - } else { - lib project: ':native:wpiutil', library: 'wpiutil', linkage: 'static' - } - } - } - } - } - } -} - -def ntcoreZipTask = { project -> - project.ext.ntcoreZip = project.tasks.create("ntcoreZip", Zip) { - description = 'Creates platform-specific zip of the desktop ntcore libraries.' - group = 'WPILib' - destinationDir = project.buildDir - baseName = 'ntcore' - if (project.isArm && project.hasProperty('compilerPrefix') - && project.hasProperty('armSuffix')) { - classifier = "${project.buildPlatform}${project.armSuffix}" - } else { - classifier = "${project.buildPlatform}" - } - duplicatesStrategy = 'exclude' - - from(file('include')) { - into 'include' - } - - if (!project.hasProperty('skipJava')) { - project.jniHeadersNetworkTables.outputs.each { - from(it) { - into 'include' - } - } - } - - project.model { - binaries { - withType(StaticLibraryBinarySpec) { binary -> - from(binary.staticLibraryFile) { - into getPlatformPath(binary) - } - } - withType(SharedLibraryBinarySpec) { binary -> - from(binary.sharedLibraryFile) { - into getPlatformPath(binary) - } - from(new File(binary.sharedLibraryFile.absolutePath + ".debug")) { - into getPlatformPath(binary) - } - } - } - } - } - - project.build.dependsOn project.ntcoreZip - - project.debugStripSetup() - - project.tasks.whenTaskAdded { task -> - def name = task.name.toLowerCase() - if (name.contains("ntcoresharedlibrary") || name.contains("ntcorestaticlibrary") || name.contains("ntcoretest")) { - project.ntcoreZip.dependsOn task - } - } -} - -if (buildArm) { - project(':arm:ntcore') { - apply plugin: 'cpp' - - apply from: "${rootDir}/toolchains/arm.gradle" - if (includeJava) { - apply from: "${rootDir}/java/java.gradle" - } - - ntcoreSetupModel(project) - ntcoreZipTask(project) - } -} - -project(':native:ntcore') { - apply plugin: 'cpp' - - apply from: "${rootDir}/toolchains/native.gradle" - - if (!project.hasProperty("withoutTests")) { - apply from: "${rootDir}/test/tests.gradle" - } - - if (includeJava) { - apply from: "${rootDir}/java/java.gradle" - } - - ntcoreSetupModel(project) - ntcoreZipTask(project) -} - -task ntcoreSourceZip(type: Zip) { - description = 'Creates a sources-zip of the ntcore source files' - group = 'WPILib' - destinationDir = project.buildDir - baseName = 'ntcore' - classifier = "sources" - duplicatesStrategy = 'exclude' - - from('src') { - into 'src' - } - - from('include') { - into 'include' - } - - if (includeJava) { - from('java/lib') { - into 'src' - } - - project(':native:ntcore').jniHeadersNetworkTables.outputs.each { - from(it) { - into 'include' - } - } - } -} diff --git a/publish.gradle b/publish.gradle index 63d7243..5ebd510 100644 --- a/publish.gradle +++ b/publish.gradle @@ -1,132 +1,222 @@ -import org.gradle.internal.os.OperatingSystem - apply plugin: 'maven-publish' apply plugin: 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' -def getVersion = { - if (WPILibVersion.version.contains('-')) - return WPILibVersion.version.substring(WPILibVersion.version.indexOf('-')) - else - return "" -} - if (!hasProperty('releaseType')) { WPILibVersion { releaseType = 'dev' } } -def ntVersion -def utilVersion -if (project.hasProperty("ntPublishVersion")) { - ntVersion = project.ntPublishVersion +def pubVersion +if (project.hasProperty("publishVersion")) { + pubVersion = project.publishVersion } else { - ntVersion = WPILibVersion.version + pubVersion = WPILibVersion.version } -if (project.hasProperty("utilPublishVersion")) { - utilVersion = project.utilPublishVersion -} else { - utilVersion = "1.0.2${-> getVersion()}" -} +def outputsFolder = file("$buildDir/outputs") -def utilFile = file("$buildDir/wpiutil.txt") -def ntcoreFile = file("$buildDir/ntcore.txt") +def versionFile = file("$outputsFolder/version.txt") task outputVersions() { - description = 'Prints the versions of ntcore and wpiutil to a file for use by the downstream packaging project' + description = 'Prints the versions of ntcore to a file for use by the downstream packaging project' group = 'Build' - outputs.files(utilFile, ntcoreFile) + outputs.files(versionFile) doFirst { - buildDir.mkdir() + outputsFolder.mkdir() } doLast { - utilFile.write utilVersion - ntcoreFile.write ntVersion + versionFile.write pubVersion } } -task clean(type: Delete) { - delete utilFile - delete ntcoreFile -} +build.dependsOn outputVersions -outputVersions.mustRunAfter clean +def baseArtifactId = 'ntcore' +def artifactGroupId = 'edu.wpi.first.ntcore' -project(':native:wpiutil').build.dependsOn outputVersions -project(':native:ntcore').build.dependsOn outputVersions -if (project.buildArm) { - project(':arm:wpiutil').build.dependsOn outputVersions - project(':arm:ntcore').build.dependsOn outputVersions -} +def licenseFile = file("$rootDir/license.txt") +task cppSourcesZip(type: Zip) { + destinationDir = outputsFolder + classifier = "sources" + from(licenseFile) { + into '/' + } -// We change what repo we publish to depending on whether this is a development, beta, stable, or full -// release. This is set up in the main gradle file. -publishing { - publications { - def nat = project('native:ntcore') - if (!project.hasProperty('skipJava')) { - java(MavenPublication) { - artifact nat.jar - artifact nat.networktablesJavaSource - artifact nat.networktablesJavadoc - if (project.buildArm) { - def natArm = project('arm:ntcore') - artifact natArm.jar - // If the library is not embedded include it in the repo - if (!project.hasProperty('compilerPrefix')) { - artifact natArm.ntcoreZip - } - } + from('src/main/native/cpp') { + into '/' + } - if (project.hasProperty('makeDesktop')) { - artifact nat.jar, { - classifier = 'desktop' + model { + tasks { + it.each { + if (it in getJNIHeadersClass()) { + from (it.outputs.files) { + into '/' } + dependsOn it } - - groupId 'edu.wpi.first.wpilib.networktables.java' - artifactId 'NetworkTables' - version ntVersion } } - cpp(MavenPublication) { - artifact nat.ntcoreZip - artifact ntcoreSourceZip - if (project.buildArm) { - artifact project(':arm:ntcore').ntcoreZip - } + } +} + +task cppHeadersZip(type: Zip) { + destinationDir = outputsFolder + classifier = "headers" + + from(licenseFile) { + into '/' + } + + from('src/main/native/include') { + into '/' + } +} + +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource +} - if (project.hasProperty('makeDesktop')) { - artifact nat.ntcoreZip, { - classifier = 'desktop' +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir +} + +if (project.hasProperty('jenkinsBuild')) { + jar { + classifier = 'javaArtifact' + } +} + +artifacts { + archives sourcesJar + archives javadocJar + archives cppHeadersZip + archives cppSourcesZip +} + +def createComponentZipTasks = { components, name, base, type, project, func -> + def configMap = [:] + components.each { + if (it in NativeLibrarySpec && it.name == name) { + it.binaries.each { + def target = getClassifier(it) + if (configMap.containsKey(target)) { + configMap.get(target).add(it) + } else { + configMap.put(target, []) + configMap.get(target).add(it) } } + } + } + def taskList = [] + configMap.each { key, value -> + def baseN = base + name + def task = project.tasks.create(baseN + "-${key}", type) { + description = 'Creates component archive for platform ' + key + destinationDir = outputsFolder + classifier = key + baseName = baseN + '-classifier' + duplicatesStrategy = 'exclude' + + from(licenseFile) { + into '/' + } - groupId 'edu.wpi.first.wpilib.networktables.cpp' - artifactId 'NetworkTables' - version ntVersion + func(it, value) } - wpiutil(MavenPublication) { - artifact project(':native:wpiutil').wpiutilZip - artifact wpiutilSourceZip - if (project.buildArm) { - artifact project(':arm:wpiutil').wpiutilZip + taskList.add(task) + + project.build.dependsOn task + + project.artifacts { + task + } + } + return taskList +} + +model { + publishing { + def ntcoreTaskList = createComponentZipTasks($.components, 'ntcore', 'zipcppntcore', Zip, project, { task, value -> + value.each { binary-> + if (binary.buildable) { + if (binary instanceof SharedLibraryBinarySpec) { + task.dependsOn binary.buildTask + task.from(new File(binary.sharedLibraryFile.absolutePath + ".debug")) { + into getPlatformPath(binary) + '/shared' + } + task.from (binary.sharedLibraryFile) { + into getPlatformPath(binary) + '/shared' + } + task.from (binary.sharedLibraryLinkFile) { + into getPlatformPath(binary) + '/shared' + } + } else if (binary instanceof StaticLibraryBinarySpec) { + task.dependsOn binary.buildTask + task.from (binary.staticLibraryFile) { + into getPlatformPath(binary) + '/static' + } + } + } + } + }) + + def ntcoreJNITaskList = createComponentZipTasks($.components, 'ntcoreJNI', 'jnijnintcore', Jar, project, { task, value -> + value.each { binary-> + if (binary.buildable) { + if (binary instanceof SharedLibraryBinarySpec) { + task.dependsOn binary.buildTask + task.from (binary.sharedLibraryFile) { + into getPlatformPath(binary) + } + } + } } + }) - if (project.hasProperty('makeDesktop')) { - artifact project(':native:wpiutil').wpiutilZip, { - classifier = 'desktop' + publications { + cpp(MavenPublication) { + ntcoreTaskList.each { + artifact it } + artifact cppHeadersZip + artifact cppSourcesZip + + artifactId = "${baseArtifactId}-cpp" + groupId artifactGroupId + version pubVersion } + jni(MavenPublication) { + ntcoreJNITaskList.each { + artifact it + } - groupId 'edu.wpi.first.wpilib' - artifactId 'wpiutil' - version utilVersion + artifactId = "${baseArtifactId}-jni" + groupId artifactGroupId + version pubVersion + } + } + } +} + +publishing { + publications { + java(MavenPublication) { + artifact jar + artifact sourcesJar + artifact javadocJar + + artifactId = "${baseArtifactId}-java" + groupId artifactGroupId + version pubVersion } } } diff --git a/settings.gradle b/settings.gradle index 1a4c2aa..da7ccc2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,8 +1 @@ -include 'native:ntcore' -include 'native:wpiutil' include 'gmock' - -if (!hasProperty('skipArm')) { - include 'arm:ntcore' - include 'arm:wpiutil' -} diff --git a/java/arm-linux/LICENSE b/src/arm-linux-jni/LICENSE similarity index 100% rename from java/arm-linux/LICENSE rename to src/arm-linux-jni/LICENSE diff --git a/java/arm-linux/jni.h b/src/arm-linux-jni/jni.h similarity index 100% rename from java/arm-linux/jni.h rename to src/arm-linux-jni/jni.h diff --git a/java/arm-linux/linux/jni_md.h b/src/arm-linux-jni/linux/jni_md.h similarity index 100% rename from java/arm-linux/linux/jni_md.h rename to src/arm-linux-jni/linux/jni_md.h diff --git a/src/dev/native/cpp/main.cpp b/src/dev/native/cpp/main.cpp new file mode 100644 index 0000000..505b3f4 --- /dev/null +++ b/src/dev/native/cpp/main.cpp @@ -0,0 +1,9 @@ +#include "ntcore.h" +#include "nt_Value.h" +#include + +int main() { + nt::SetEntryValue("MyValue", nt::Value::MakeString("Hello World")); + + std::cout << nt::GetEntryValue("MyValue")->GetString() << std::endl; +} diff --git a/java/src/edu/wpi/first/wpilibj/networktables/ConnectionInfo.java b/src/main/java/edu/wpi/first/wpilibj/networktables/ConnectionInfo.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/networktables/ConnectionInfo.java rename to src/main/java/edu/wpi/first/wpilibj/networktables/ConnectionInfo.java diff --git a/java/src/edu/wpi/first/wpilibj/networktables/EntryInfo.java b/src/main/java/edu/wpi/first/wpilibj/networktables/EntryInfo.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/networktables/EntryInfo.java rename to src/main/java/edu/wpi/first/wpilibj/networktables/EntryInfo.java diff --git a/java/src/edu/wpi/first/wpilibj/networktables/NetworkTable.java b/src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTable.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/networktables/NetworkTable.java rename to src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTable.java diff --git a/java/src/edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined.java b/src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined.java rename to src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined.java diff --git a/java/src/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java b/src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java similarity index 93% rename from java/src/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java rename to src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java index 516332f..6689b0f 100644 --- a/java/src/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java +++ b/src/main/java/edu/wpi/first/wpilibj/networktables/NetworkTablesJNI.java @@ -8,6 +8,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; +import edu.wpi.first.wpiutil.RuntimeDetector; public class NetworkTablesJNI { static boolean libraryLoaded = false; @@ -18,19 +19,7 @@ public class NetworkTablesJNI { System.loadLibrary("ntcore"); } catch (UnsatisfiedLinkError e) { try { - String osname = System.getProperty("os.name"); - String resname; - if (osname.startsWith("Windows")) - resname = "/Windows/" + System.getProperty("os.arch") + "/"; - else - resname = "/" + osname + "/" + System.getProperty("os.arch") + "/"; - System.out.println("platform: " + resname); - if (osname.startsWith("Windows")) - resname += "ntcore.dll"; - else if (osname.startsWith("Mac")) - resname += "libntcore.dylib"; - else - resname += "libntcore.so"; + String resname = RuntimeDetector.getLibraryResource("ntcore"); InputStream is = NetworkTablesJNI.class.getResourceAsStream(resname); if (is != null) { // create temporary file diff --git a/java/src/edu/wpi/first/wpilibj/networktables/PersistentException.java b/src/main/java/edu/wpi/first/wpilibj/networktables/PersistentException.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/networktables/PersistentException.java rename to src/main/java/edu/wpi/first/wpilibj/networktables/PersistentException.java diff --git a/java/src/edu/wpi/first/wpilibj/networktables2/type/ArrayData.java b/src/main/java/edu/wpi/first/wpilibj/networktables2/type/ArrayData.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/networktables2/type/ArrayData.java rename to src/main/java/edu/wpi/first/wpilibj/networktables2/type/ArrayData.java diff --git a/java/src/edu/wpi/first/wpilibj/networktables2/type/BooleanArray.java b/src/main/java/edu/wpi/first/wpilibj/networktables2/type/BooleanArray.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/networktables2/type/BooleanArray.java rename to src/main/java/edu/wpi/first/wpilibj/networktables2/type/BooleanArray.java diff --git a/java/src/edu/wpi/first/wpilibj/networktables2/type/NumberArray.java b/src/main/java/edu/wpi/first/wpilibj/networktables2/type/NumberArray.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/networktables2/type/NumberArray.java rename to src/main/java/edu/wpi/first/wpilibj/networktables2/type/NumberArray.java diff --git a/java/src/edu/wpi/first/wpilibj/networktables2/type/StringArray.java b/src/main/java/edu/wpi/first/wpilibj/networktables2/type/StringArray.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/networktables2/type/StringArray.java rename to src/main/java/edu/wpi/first/wpilibj/networktables2/type/StringArray.java diff --git a/java/src/edu/wpi/first/wpilibj/tables/IRemote.java b/src/main/java/edu/wpi/first/wpilibj/tables/IRemote.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/tables/IRemote.java rename to src/main/java/edu/wpi/first/wpilibj/tables/IRemote.java diff --git a/java/src/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java b/src/main/java/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java rename to src/main/java/edu/wpi/first/wpilibj/tables/IRemoteConnectionListener.java diff --git a/java/src/edu/wpi/first/wpilibj/tables/ITable.java b/src/main/java/edu/wpi/first/wpilibj/tables/ITable.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/tables/ITable.java rename to src/main/java/edu/wpi/first/wpilibj/tables/ITable.java diff --git a/java/src/edu/wpi/first/wpilibj/tables/ITableListener.java b/src/main/java/edu/wpi/first/wpilibj/tables/ITableListener.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/tables/ITableListener.java rename to src/main/java/edu/wpi/first/wpilibj/tables/ITableListener.java diff --git a/java/src/edu/wpi/first/wpilibj/tables/TableKeyNotDefinedException.java b/src/main/java/edu/wpi/first/wpilibj/tables/TableKeyNotDefinedException.java similarity index 100% rename from java/src/edu/wpi/first/wpilibj/tables/TableKeyNotDefinedException.java rename to src/main/java/edu/wpi/first/wpilibj/tables/TableKeyNotDefinedException.java diff --git a/src/Dispatcher.cpp b/src/main/native/cpp/Dispatcher.cpp similarity index 100% rename from src/Dispatcher.cpp rename to src/main/native/cpp/Dispatcher.cpp diff --git a/src/Dispatcher.h b/src/main/native/cpp/Dispatcher.h similarity index 100% rename from src/Dispatcher.h rename to src/main/native/cpp/Dispatcher.h diff --git a/src/DsClient.cpp b/src/main/native/cpp/DsClient.cpp similarity index 100% rename from src/DsClient.cpp rename to src/main/native/cpp/DsClient.cpp diff --git a/src/DsClient.h b/src/main/native/cpp/DsClient.h similarity index 100% rename from src/DsClient.h rename to src/main/native/cpp/DsClient.h diff --git a/src/Log.cpp b/src/main/native/cpp/Log.cpp similarity index 100% rename from src/Log.cpp rename to src/main/native/cpp/Log.cpp diff --git a/src/Log.h b/src/main/native/cpp/Log.h similarity index 100% rename from src/Log.h rename to src/main/native/cpp/Log.h diff --git a/src/Message.cpp b/src/main/native/cpp/Message.cpp similarity index 100% rename from src/Message.cpp rename to src/main/native/cpp/Message.cpp diff --git a/src/Message.h b/src/main/native/cpp/Message.h similarity index 100% rename from src/Message.h rename to src/main/native/cpp/Message.h diff --git a/src/NetworkConnection.cpp b/src/main/native/cpp/NetworkConnection.cpp similarity index 100% rename from src/NetworkConnection.cpp rename to src/main/native/cpp/NetworkConnection.cpp diff --git a/src/NetworkConnection.h b/src/main/native/cpp/NetworkConnection.h similarity index 100% rename from src/NetworkConnection.h rename to src/main/native/cpp/NetworkConnection.h diff --git a/src/Notifier.cpp b/src/main/native/cpp/Notifier.cpp similarity index 100% rename from src/Notifier.cpp rename to src/main/native/cpp/Notifier.cpp diff --git a/src/Notifier.h b/src/main/native/cpp/Notifier.h similarity index 100% rename from src/Notifier.h rename to src/main/native/cpp/Notifier.h diff --git a/src/RpcServer.cpp b/src/main/native/cpp/RpcServer.cpp similarity index 100% rename from src/RpcServer.cpp rename to src/main/native/cpp/RpcServer.cpp diff --git a/src/RpcServer.h b/src/main/native/cpp/RpcServer.h similarity index 100% rename from src/RpcServer.h rename to src/main/native/cpp/RpcServer.h diff --git a/src/SequenceNumber.cpp b/src/main/native/cpp/SequenceNumber.cpp similarity index 100% rename from src/SequenceNumber.cpp rename to src/main/native/cpp/SequenceNumber.cpp diff --git a/src/SequenceNumber.h b/src/main/native/cpp/SequenceNumber.h similarity index 100% rename from src/SequenceNumber.h rename to src/main/native/cpp/SequenceNumber.h diff --git a/src/Storage.cpp b/src/main/native/cpp/Storage.cpp similarity index 100% rename from src/Storage.cpp rename to src/main/native/cpp/Storage.cpp diff --git a/src/Storage.h b/src/main/native/cpp/Storage.h similarity index 100% rename from src/Storage.h rename to src/main/native/cpp/Storage.h diff --git a/src/Value.cpp b/src/main/native/cpp/Value.cpp similarity index 100% rename from src/Value.cpp rename to src/main/native/cpp/Value.cpp diff --git a/src/Value_internal.h b/src/main/native/cpp/Value_internal.h similarity index 100% rename from src/Value_internal.h rename to src/main/native/cpp/Value_internal.h diff --git a/src/WireDecoder.cpp b/src/main/native/cpp/WireDecoder.cpp similarity index 100% rename from src/WireDecoder.cpp rename to src/main/native/cpp/WireDecoder.cpp diff --git a/src/WireDecoder.h b/src/main/native/cpp/WireDecoder.h similarity index 100% rename from src/WireDecoder.h rename to src/main/native/cpp/WireDecoder.h diff --git a/src/WireEncoder.cpp b/src/main/native/cpp/WireEncoder.cpp similarity index 100% rename from src/WireEncoder.cpp rename to src/main/native/cpp/WireEncoder.cpp diff --git a/src/WireEncoder.h b/src/main/native/cpp/WireEncoder.h similarity index 100% rename from src/WireEncoder.h rename to src/main/native/cpp/WireEncoder.h diff --git a/java/lib/NetworkTablesJNI.cpp b/src/main/native/cpp/jni/NetworkTablesJNI.cpp similarity index 100% rename from java/lib/NetworkTablesJNI.cpp rename to src/main/native/cpp/jni/NetworkTablesJNI.cpp diff --git a/src/networktables/NetworkTable.cpp b/src/main/native/cpp/networktables/NetworkTable.cpp similarity index 100% rename from src/networktables/NetworkTable.cpp rename to src/main/native/cpp/networktables/NetworkTable.cpp diff --git a/src/ntcore_c.cpp b/src/main/native/cpp/ntcore_c.cpp similarity index 100% rename from src/ntcore_c.cpp rename to src/main/native/cpp/ntcore_c.cpp diff --git a/src/ntcore_cpp.cpp b/src/main/native/cpp/ntcore_cpp.cpp similarity index 100% rename from src/ntcore_cpp.cpp rename to src/main/native/cpp/ntcore_cpp.cpp diff --git a/src/ntcore_test.cpp b/src/main/native/cpp/ntcore_test.cpp similarity index 100% rename from src/ntcore_test.cpp rename to src/main/native/cpp/ntcore_test.cpp diff --git a/src/tables/ITableListener.cpp b/src/main/native/cpp/tables/ITableListener.cpp similarity index 100% rename from src/tables/ITableListener.cpp rename to src/main/native/cpp/tables/ITableListener.cpp diff --git a/src/tables/TableKeyNotDefinedException.cpp b/src/main/native/cpp/tables/TableKeyNotDefinedException.cpp similarity index 100% rename from src/tables/TableKeyNotDefinedException.cpp rename to src/main/native/cpp/tables/TableKeyNotDefinedException.cpp diff --git a/include/networktables/NetworkTable.h b/src/main/native/include/networktables/NetworkTable.h similarity index 100% rename from include/networktables/NetworkTable.h rename to src/main/native/include/networktables/NetworkTable.h diff --git a/include/nt_Value.h b/src/main/native/include/nt_Value.h similarity index 100% rename from include/nt_Value.h rename to src/main/native/include/nt_Value.h diff --git a/include/ntcore.h b/src/main/native/include/ntcore.h similarity index 100% rename from include/ntcore.h rename to src/main/native/include/ntcore.h diff --git a/include/ntcore_c.h b/src/main/native/include/ntcore_c.h similarity index 100% rename from include/ntcore_c.h rename to src/main/native/include/ntcore_c.h diff --git a/include/ntcore_cpp.h b/src/main/native/include/ntcore_cpp.h similarity index 100% rename from include/ntcore_cpp.h rename to src/main/native/include/ntcore_cpp.h diff --git a/include/ntcore_test.h b/src/main/native/include/ntcore_test.h similarity index 100% rename from include/ntcore_test.h rename to src/main/native/include/ntcore_test.h diff --git a/include/tables/ITable.h b/src/main/native/include/tables/ITable.h similarity index 100% rename from include/tables/ITable.h rename to src/main/native/include/tables/ITable.h diff --git a/include/tables/ITableListener.h b/src/main/native/include/tables/ITableListener.h similarity index 100% rename from include/tables/ITableListener.h rename to src/main/native/include/tables/ITableListener.h diff --git a/include/tables/TableKeyNotDefinedException.h b/src/main/native/include/tables/TableKeyNotDefinedException.h similarity index 100% rename from include/tables/TableKeyNotDefinedException.h rename to src/main/native/include/tables/TableKeyNotDefinedException.h diff --git a/src/test/java/edu/wpi/first/wpilibj/networktables/JNITest.java b/src/test/java/edu/wpi/first/wpilibj/networktables/JNITest.java new file mode 100644 index 0000000..52e1951 --- /dev/null +++ b/src/test/java/edu/wpi/first/wpilibj/networktables/JNITest.java @@ -0,0 +1,11 @@ +package edu.wpi.first.wpilibj.networktables; + +import org.junit.Test; + +public class JNITest { + @Test + public void jniLinkTest() { + // Test to verify that the JNI test link works correctly. + edu.wpi.first.wpilibj.networktables.NetworkTablesJNI.flush(); + } +} diff --git a/test/unit/NetworkTableTest.cpp b/src/test/native/cpp/NetworkTableTest.cpp similarity index 100% rename from test/unit/NetworkTableTest.cpp rename to src/test/native/cpp/NetworkTableTest.cpp diff --git a/test/unit/StorageTest.cpp b/src/test/native/cpp/StorageTest.cpp similarity index 100% rename from test/unit/StorageTest.cpp rename to src/test/native/cpp/StorageTest.cpp diff --git a/test/unit/StorageTest.h b/src/test/native/cpp/StorageTest.h similarity index 100% rename from test/unit/StorageTest.h rename to src/test/native/cpp/StorageTest.h diff --git a/test/unit/ValueTest.cpp b/src/test/native/cpp/ValueTest.cpp similarity index 100% rename from test/unit/ValueTest.cpp rename to src/test/native/cpp/ValueTest.cpp diff --git a/test/unit/WireDecoderTest.cpp b/src/test/native/cpp/WireDecoderTest.cpp similarity index 100% rename from test/unit/WireDecoderTest.cpp rename to src/test/native/cpp/WireDecoderTest.cpp diff --git a/test/unit/WireEncoderTest.cpp b/src/test/native/cpp/WireEncoderTest.cpp similarity index 100% rename from test/unit/WireEncoderTest.cpp rename to src/test/native/cpp/WireEncoderTest.cpp diff --git a/test/unit/main.cpp b/src/test/native/cpp/main.cpp similarity index 100% rename from test/unit/main.cpp rename to src/test/native/cpp/main.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index 732b0a3..0000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -add_subdirectory(unit) - -if(MSVC) -set(NTCORE_LIB ntcore_static) -else() -set(NTCORE_LIB ntcore) -endif() - -add_executable(client client.cpp) -target_link_libraries(client ${NTCORE_LIB} ${CMAKE_THREAD_LIBS_INIT}) -add_executable(server server.cpp) -target_link_libraries(server ${NTCORE_LIB} ${CMAKE_THREAD_LIBS_INIT}) -add_executable(rpc_local rpc_local.cpp) -target_link_libraries(rpc_local ${NTCORE_LIB} ${CMAKE_THREAD_LIBS_INIT}) -add_executable(rpc_speed rpc_speed.cpp) -target_link_libraries(rpc_speed ${NTCORE_LIB} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/test/tests.gradle b/test/tests.gradle deleted file mode 100644 index 829336d..0000000 --- a/test/tests.gradle +++ /dev/null @@ -1,42 +0,0 @@ -apply plugin: 'google-test' - -model { - testSuites { - ntcoreTest { - if (!project.hasProperty('skipJava')) { - setupJniIncludes(binaries) - } - sources { - cpp { - source { - srcDirs = ["${rootDir}/test/unit"] - includes = ['**/*.cpp'] - } - exportedHeaders { - srcDirs = ["${rootDir}/include", "${rootDir}/src", "${rootDir}/wpiutil/include", "${rootDir}/gmock/include", "${rootDir}/gmock/gtest/include"] - includes = ['**/*.h'] - } - } - } - binaries.all { - lib project: ':gmock', library: 'gmock', linkage: 'static' - lib library: 'ntcore', linkage: 'static' - } - } - } -} - -model { - binaries { - withType(GoogleTestTestSuiteBinarySpec) { - lib project: ':gmock', library: "gmock", linkage: "static" - lib library: 'ntcore', linkage: 'static' - if (targetPlatform.operatingSystem.windows) { - cppCompiler.args '/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS' - } else { - cppCompiler.args '-pthread', '-std=c++1y' - linker.args '-pthread' - } - } - } -} diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt deleted file mode 100644 index 4929b1e..0000000 --- a/test/unit/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -file(GLOB SRCS *.cpp) - -add_executable(testntcore ${SRCS}) -add_test(testntcore testntcore) - -if(MSVC) -target_link_libraries(testntcore - ntcore_static - gmock - gtest - ) -else() -target_link_libraries(testntcore - ntcore - gmock - gtest - ) -endif() diff --git a/toolchains/arm.gradle b/toolchains/arm.gradle deleted file mode 100644 index 90a8758..0000000 --- a/toolchains/arm.gradle +++ /dev/null @@ -1,100 +0,0 @@ -ext.isArm = true -ext.buildPlatform = 'arm' - -def compilerPrefix = project.hasProperty('compilerPrefix') ? project.compilerPrefix : 'arm-frc-linux-gnueabi-' -def toolChainPath = project.hasProperty('toolChainPath') ? project.toolChainPath : null -model { - platforms { - arm { - architecture 'arm' - operatingSystem 'linux' - } - } - toolChains { - armGcc(Gcc) { - if (toolChainPath != null) path(toolChainPath) - target("arm") { - // We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi- - // If this ever changes, the prefix will need to be changed here - cCompiler.executable = compilerPrefix + cCompiler.executable - cppCompiler.executable = compilerPrefix + cppCompiler.executable - linker.executable = compilerPrefix + linker.executable - assembler.executable = compilerPrefix + assembler.executable - // Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports - // arm, and doesn't understand this flag, so it is removed from both - cppCompiler.withArguments { args -> - args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic' - args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-rdynamic' - //TODO: When the compiler allows us to actually call deprecated functions from within - // deprecated function, remove this line (this will cause calling deprecated functions - // to be treated as a warning rather than an error). - args << '-Wno-error=deprecated-declarations' << '-pthread' - args.remove('-m32') - } - linker.withArguments { args -> - args << '-rdynamic' << '-pthread' - args.remove('-m32') - } - staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable - } - } - } -} - -ext.binTools = { tool -> - if (toolChainPath != null) return "${toolChainPath}/${compilerPrefix}${tool}" - return "${compilerPrefix}${tool}" -} - -ext.setupReleaseDefines = { cppCompiler, linker -> - cppCompiler.args '-O2', '-g' -} - -ext.setupDebugDefines = { cppCompiler, linker -> - cppCompiler.args '-g', '-O0' -} - -// Used only on Windows. -ext.setupDef = { linker, deffile -> } - -ext.debugStripSetup = { - if (!project.hasProperty('debug')) { - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - def debugLibrary = task.outputFile.absolutePath + ".debug" - task.doLast { - exec { commandLine binTools('objcopy'), '--only-keep-debug', library, debugLibrary } - exec { commandLine binTools('strip'), '-g', library } - exec { commandLine binTools('objcopy'), "--add-gnu-debuglink=$debugLibrary", library } - } - } - } - } -} - -ext.checkNativeSymbols = { getSymbolFunc -> - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - task.doLast { - def nmOutput = new ByteArrayOutputStream() - exec { - commandLine binTools('nm'), library - standardOutput nmOutput - } - // Remove '\r' so we can check for full string contents - String nmSymbols = nmOutput.toString().replace('\r', '') - - def symbolList = getSymbolFunc() - symbolList.each { - //Add \n so we can check for the exact symbol - def found = nmSymbols.contains(it + '\n') - if (!found) { - throw new GradleException("Found a definition that does not have a matching symbol ${it}") - } - } - } - } - } -} diff --git a/toolchains/linux.gradle b/toolchains/linux.gradle deleted file mode 100644 index cea85b4..0000000 --- a/toolchains/linux.gradle +++ /dev/null @@ -1,87 +0,0 @@ -model { - toolChains { - gcc(Gcc) { - target('x86') { - cppCompiler.withArguments { args -> - args << '-std=c++11' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic' - args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-rdynamic' - //TODO: When the compiler allows us to actually call deprecated functions from within - // deprecated function, remove this line (this will cause calling deprecated functions - // to be treated as a warning rather than an error). - args << '-Wno-error=deprecated-declarations' << '-pthread' - args << '-m32' - } - linker.withArguments { args -> - args << '-rdynamic' << '-pthread' - args << '-m32' - } - } - target('x64') { - cppCompiler.withArguments { args -> - args << '-std=c++11' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic' - args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-rdynamic' - //TODO: When the compiler allows us to actually call deprecated functions from within - // deprecated function, remove this line (this will cause calling deprecated functions - // to be treated as a warning rather than an error). - args << '-Wno-error=deprecated-declarations' << '-pthread' - } - linker.withArguments { args -> - args << '-rdynamic' << '-pthread' - } - } - } - } -} - -ext.setupReleaseDefines = { cppCompiler, linker -> - cppCompiler.args '-O2', '-g' -} - -ext.setupDebugDefines = { cppCompiler, linker -> - cppCompiler.args '-g', '-O0' -} - -// Used only on Windows. -ext.setupDef = { linker, deffile -> } - -ext.debugStripSetup = { - if (!project.hasProperty('debug')) { - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - def debugLibrary = task.outputFile.absolutePath + ".debug" - task.doLast { - exec { commandLine "objcopy", '--only-keep-debug', library, debugLibrary } - exec { commandLine "strip", '-g', library } - exec { commandLine "objcopy", "--add-gnu-debuglink=$debugLibrary", library } - } - } - } - } -} - -ext.checkNativeSymbols = { getSymbolFunc -> - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - task.doLast { - def nmOutput = new ByteArrayOutputStream() - exec { - commandLine "nm", library - standardOutput nmOutput - } - // Remove '\r' so we can check for full string contents - String nmSymbols = nmOutput.toString().replace('\r', '') - - def symbolList = getSymbolFunc() - symbolList.each { - //Add \n so we can check for the exact symbol - def found = nmSymbols.contains(it + '\n') - if (!found) { - throw new GradleException("Found a definition that does not have a matching symbol ${it}") - } - } - } - } - } -} diff --git a/toolchains/mac.gradle b/toolchains/mac.gradle deleted file mode 100644 index 902cbb5..0000000 --- a/toolchains/mac.gradle +++ /dev/null @@ -1,74 +0,0 @@ -model { - toolChains { - clang(Clang) { - target('x86') { - cppCompiler.withArguments { args -> - args << '-std=c++11' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic-errors' - args << '-fPIC' << '-m32' - args << '-Wno-unused-parameter' << '-Wno-missing-field-initializers' << '-Wno-unused-private-field' - } - linker.withArguments { args -> - args << '-m32' - } - } - target('x64') { - cppCompiler.withArguments { args -> - args << '-std=c++11' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic-errors' - args << '-fPIC' - args << '-Wno-missing-field-initializers' << '-Wno-unused-private-field' << '-Wno-unused-parameter' - } - } - } - } -} - -ext.setupReleaseDefines = { cppCompiler, linker -> - cppCompiler.args '-O2' -} - -ext.setupDebugDefines = { cppCompiler, linker -> - cppCompiler.args '-g', '-O0' -} - -// Used only on Windows. -ext.setupDef = { linker, deffile -> } - -ext.debugStripSetup = { - if (!project.hasProperty('debug')) { - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - task.doLast { - exec { commandLine "dsymutil", library } - exec { commandLine "strip", '-S', library } - } - } - } - } -} - -ext.checkNativeSymbols = { getSymbolFunc -> - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - task.doLast { - def nmOutput = new ByteArrayOutputStream() - exec { - commandLine "nm", library - standardOutput nmOutput - } - // Remove '\r' so we can check for full string contents - String nmSymbols = nmOutput.toString().replace('\r', '') - - def symbolList = getSymbolFunc() - symbolList.each { - //Add \n so we can check for the exact symbol - def found = nmSymbols.contains(it + '\n') - if (!found) { - throw new GradleException("Found a definition that does not have a matching symbol ${it}") - } - } - } - } - } -} diff --git a/toolchains/native.gradle b/toolchains/native.gradle deleted file mode 100644 index 10d8b8a..0000000 --- a/toolchains/native.gradle +++ /dev/null @@ -1,25 +0,0 @@ -import org.gradle.internal.os.OperatingSystem - -ext.isArm = false -ext.buildPlatform = OperatingSystem.current().getFamilyName() - -if (OperatingSystem.current().isLinux()) { - apply from: "${rootDir}/toolchains/linux.gradle" -} else if (OperatingSystem.current().isMacOsX()) { - apply from: "${rootDir}/toolchains/mac.gradle" -} else if (OperatingSystem.current().isWindows()) { - apply from: "${rootDir}/toolchains/windows.gradle" -} else { - throw new GradleException("${name} does not support building on ${ext.buildPlatform}.") -} - -model { - platforms { - x86 { - architecture 'x86' - } - x64 { - architecture 'x86_64' - } - } -} diff --git a/toolchains/windows.gradle b/toolchains/windows.gradle deleted file mode 100644 index f565934..0000000 --- a/toolchains/windows.gradle +++ /dev/null @@ -1,33 +0,0 @@ -model { - toolChains { - visualCpp(VisualCpp) { - - eachPlatform { - cppCompiler.withArguments { args -> - args << '/EHsc' << '/DNOMINMAX' << '/D_SCL_SECURE_NO_WARNINGS' << '/D_WINSOCK_DEPRECATED_NO_WARNINGS' - } - } - } - } -} - -ext.setupReleaseDefines = { cppCompiler, linker -> - cppCompiler.args '/O2', '/Zi', '/FS' -} - -ext.setupDebugDefines = { cppCompiler, linker -> - cppCompiler.args '/Zi', '/FS' - linker.args '/DEBUG' -} - -ext.setupDef = { linker, deffile -> - linker.args "/DEF:${deffile}" -} - -// This is a noop on Windows. On gcc platforms, we strip the release binary and create a separate -// debug library, but Windows already separates debug symbols into a .pdb file. -ext.debugStripSetup = { } - -// This is a noop on Windows. The def file already implicilty checks for the symbols -ext.checkNativeSymbols = { getSymbolFunc -> -} diff --git a/wpiutil.gradle b/wpiutil.gradle deleted file mode 100644 index 6cd9fab..0000000 --- a/wpiutil.gradle +++ /dev/null @@ -1,119 +0,0 @@ -def wpiutilSetupModel = { project -> - project.model { - components { - wpiutil(NativeLibrarySpec) { - if (project.isArm) { - targetPlatform 'arm' - } else { - targetPlatform 'x86' - targetPlatform 'x64' - } - setupDefines(project, binaries) - - sources { - cpp { - source { - srcDirs = ["${rootDir}/wpiutil/src"] - includes = ['**/*.cpp'] - } - exportedHeaders { - srcDirs = ["${rootDir}/wpiutil/include"] - includes = ['**/*.h'] - } - } - } - } - } - } -} - - -def wpiutilZipTask = { project -> - project.ext.wpiutilZip = project.tasks.create("wpiutilZip", Zip) { - description = 'Creates platform-specific zip of the desktop wpiutil libraries.' - group = 'WPILib' - destinationDir = project.buildDir - baseName = 'wpiutil' - if (project.isArm && project.hasProperty('compilerPrefix') - && project.hasProperty('armSuffix')) { - classifier = "${project.buildPlatform}${project.armSuffix}" - } else { - classifier = "${project.buildPlatform}" - } - duplicatesStrategy = 'exclude' - - from(file('wpiutil/include')) { - into 'include' - } - - project.model { - binaries { - withType(StaticLibraryBinarySpec) { binary -> - from(binary.staticLibraryFile) { - into getPlatformPath(binary) - } - } - withType(SharedLibraryBinarySpec) { binary -> - from(binary.sharedLibraryFile) { - into getPlatformPath(binary) - } - from(new File(binary.sharedLibraryFile.absolutePath + ".debug")) { - into getPlatformPath(binary) - } - } - } - } - } - - project.build.dependsOn project.wpiutilZip - - project.debugStripSetup() - - project.tasks.whenTaskAdded { task -> - def name = task.name.toLowerCase() - if (name.contains("wpiutilsharedlibrary") || name.contains("wpiutilstaticlibrary") || name.contains("wpiutiltest")) { - project.wpiutilZip.dependsOn task - } - } -} - -if (buildArm) { - project(':arm:wpiutil') { - apply plugin: 'cpp' - - apply from: "${rootDir}/toolchains/arm.gradle" - - wpiutilSetupModel(project) - wpiutilZipTask(project) - } -} - -project(':native:wpiutil') { - apply plugin: 'cpp' - - apply from: "${rootDir}/toolchains/native.gradle" - - if (!project.hasProperty("withoutTests")) { - apply from: "${rootDir}/wpiutil/unittest/unittest.gradle" - } - - wpiutilSetupModel(project) - wpiutilZipTask(project) -} - -task wpiutilSourceZip(type: Zip) { - description = 'Creates a sources-zip of the wpiutil source files' - group = 'WPILib' - destinationDir = project.buildDir - baseName = 'wpiutil' - classifier = "sources" - duplicatesStrategy = 'exclude' - - from('wpiutil/src') { - into 'src' - } - - from('wpiutil/include') { - into 'include' - } -} diff --git a/wpiutil/include/llvm/AlignOf.h b/wpiutil/include/llvm/AlignOf.h deleted file mode 100644 index d54328b..0000000 --- a/wpiutil/include/llvm/AlignOf.h +++ /dev/null @@ -1,259 +0,0 @@ -//===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the AlignOf function that computes alignments for -// arbitrary types. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_ALIGNOF_H -#define LLVM_SUPPORT_ALIGNOF_H - -#include "llvm/Compiler.h" -#include -#include - -namespace llvm { - -namespace detail { - -// For everything other than an abstract class we can calulate alignment by -// building a class with a single character and a member of the given type. -template ::value> -struct AlignmentCalcImpl { - char x; -#if defined(_MSC_VER) -// Disables "structure was padded due to __declspec(align())" warnings that are -// generated by any class using AlignOf with a manually specified alignment. -// Although the warning is disabled in the LLVM project we need this pragma -// as AlignOf.h is a published support header that's available for use -// out-of-tree, and we would like that to compile cleanly at /W4. -#pragma warning(suppress : 4324) -#endif - T t; -private: - AlignmentCalcImpl() = delete; -}; - -// Abstract base class helper, this will have the minimal alignment and size -// for any abstract class. We don't even define its destructor because this -// type should never be used in a way that requires it. -struct AlignmentCalcImplBase { - virtual ~AlignmentCalcImplBase() = 0; -}; - -// When we have an abstract class type, specialize the alignment computation -// engine to create another abstract class that derives from both an empty -// abstract base class and the provided type. This has the same effect as the -// above except that it handles the fact that we can't actually create a member -// of type T. -template -struct AlignmentCalcImpl : AlignmentCalcImplBase, T { - ~AlignmentCalcImpl() override = 0; -}; - -} // End detail namespace. - -/// AlignOf - A templated class that contains an enum value representing -/// the alignment of the template argument. For example, -/// AlignOf::Alignment represents the alignment of type "int". The -/// alignment calculated is the minimum alignment, and not necessarily -/// the "desired" alignment returned by GCC's __alignof__ (for example). Note -/// that because the alignment is an enum value, it can be used as a -/// compile-time constant (e.g., for template instantiation). -template -struct AlignOf { -#ifndef _MSC_VER - // Avoid warnings from GCC like: - // comparison between 'enum llvm::AlignOf::' and 'enum - // llvm::AlignOf::' [-Wenum-compare] - // by using constexpr instead of enum. - // (except on MSVC, since it doesn't support constexpr yet). - static constexpr unsigned Alignment = static_cast( - sizeof(detail::AlignmentCalcImpl) - sizeof(T)); -#else - enum { - Alignment = static_cast( - sizeof(::llvm::detail::AlignmentCalcImpl) - sizeof(T)) - }; -#endif - enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 }; - enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 }; - enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 }; - enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 }; - - enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 }; - enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 }; - enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 }; - enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 }; -}; - -#ifndef _MSC_VER -template constexpr unsigned AlignOf::Alignment; -#endif - -/// alignOf - A templated function that returns the minimum alignment of -/// of a type. This provides no extra functionality beyond the AlignOf -/// class besides some cosmetic cleanliness. Example usage: -/// alignOf() returns the alignment of an int. -template -inline unsigned alignOf() { return AlignOf::Alignment; } - -/// \struct AlignedCharArray -/// \brief Helper for building an aligned character array type. -/// -/// This template is used to explicitly build up a collection of aligned -/// character array types. We have to build these up using a macro and explicit -/// specialization to cope with old versions of MSVC and GCC where only an -/// integer literal can be used to specify an alignment constraint. Once built -/// up here, we can then begin to indirect between these using normal C++ -/// template parameters. - -// MSVC requires special handling here. -#ifndef _MSC_VER - -#if __has_feature(cxx_alignas) -template -struct AlignedCharArray { - alignas(Alignment) char buffer[Size]; -}; - -#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES) -/// \brief Create a type with an aligned char buffer. -template -struct AlignedCharArray; - -#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ - template \ - struct AlignedCharArray { \ - __attribute__((aligned(x))) char buffer[Size]; \ - }; - -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) - -#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT - -#else -# error No supported align as directive. -#endif - -#else // _MSC_VER - -/// \brief Create a type with an aligned char buffer. -template -struct AlignedCharArray; - -// We provide special variations of this template for the most common -// alignments because __declspec(align(...)) doesn't actually work when it is -// a member of a by-value function argument in MSVC, even if the alignment -// request is something reasonably like 8-byte or 16-byte. Note that we can't -// even include the declspec with the union that forces the alignment because -// MSVC warns on the existence of the declspec despite the union member forcing -// proper alignment. - -template -struct AlignedCharArray<1, Size> { - union { - char aligned; - char buffer[Size]; - }; -}; - -template -struct AlignedCharArray<2, Size> { - union { - short aligned; - char buffer[Size]; - }; -}; - -template -struct AlignedCharArray<4, Size> { - union { - int aligned; - char buffer[Size]; - }; -}; - -template -struct AlignedCharArray<8, Size> { - union { - double aligned; - char buffer[Size]; - }; -}; - - -// The rest of these are provided with a __declspec(align(...)) and we simply -// can't pass them by-value as function arguments on MSVC. - -#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ - template \ - struct AlignedCharArray { \ - __declspec(align(x)) char buffer[Size]; \ - }; - -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64) -LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) - -#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT - -#endif // _MSC_VER - -namespace detail { -template -class AlignerImpl { - T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10; - - AlignerImpl() = delete; -}; - -template -union SizerImpl { - char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)], - arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)], - arr9[sizeof(T9)], arr10[sizeof(T10)]; -}; -} // end namespace detail - -/// \brief This union template exposes a suitably aligned and sized character -/// array member which can hold elements of any of up to ten types. -/// -/// These types may be arrays, structs, or any other types. The goal is to -/// expose a char array buffer member which can be used as suitable storage for -/// a placement new of any of these types. Support for more than ten types can -/// be added at the cost of more boilerplate. -template -struct AlignedCharArrayUnion : llvm::AlignedCharArray< - AlignOf >::Alignment, - sizeof(::llvm::detail::SizerImpl)> { -}; -} // end namespace llvm - -#endif // LLVM_SUPPORT_ALIGNOF_H diff --git a/wpiutil/include/llvm/ArrayRef.h b/wpiutil/include/llvm/ArrayRef.h deleted file mode 100644 index 4e7cd1a..0000000 --- a/wpiutil/include/llvm/ArrayRef.h +++ /dev/null @@ -1,397 +0,0 @@ -//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_ARRAYREF_H -#define LLVM_ADT_ARRAYREF_H - -#include "llvm/Compiler.h" -#include "llvm/Hashing.h" -#include "llvm/None.h" -#include "llvm/SmallVector.h" -#include - -namespace llvm { - /// ArrayRef - Represent a constant reference to an array (0 or more elements - /// consecutively in memory), i.e. a start pointer and a length. It allows - /// various APIs to take consecutive elements easily and conveniently. - /// - /// This class does not own the underlying data, it is expected to be used in - /// situations where the data resides in some other buffer, whose lifetime - /// extends past that of the ArrayRef. For this reason, it is not in general - /// safe to store an ArrayRef. - /// - /// This is intended to be trivially copyable, so it should be passed by - /// value. - template - class ArrayRef { - public: - typedef const T *iterator; - typedef const T *const_iterator; - typedef size_t size_type; - - typedef std::reverse_iterator reverse_iterator; - - private: - /// The start of the array, in an external buffer. - const T *Data; - - /// The number of elements. - size_type Length; - - public: - /// @name Constructors - /// @{ - - /// Construct an empty ArrayRef. - /*implicit*/ ArrayRef() : Data(nullptr), Length(0) {} - - /// Construct an empty ArrayRef from None. - /*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {} - - /// Construct an ArrayRef from a single element. - /*implicit*/ ArrayRef(const T &OneElt) - : Data(&OneElt), Length(1) {} - - /// Construct an ArrayRef from a pointer and length. - /*implicit*/ ArrayRef(const T *data, size_t length) - : Data(data), Length(length) {} - - /// Construct an ArrayRef from a range. - ArrayRef(const T *begin, const T *end) - : Data(begin), Length(end - begin) {} - - /// Construct an ArrayRef from a SmallVector. This is templated in order to - /// avoid instantiating SmallVectorTemplateCommon whenever we - /// copy-construct an ArrayRef. - template - /*implicit*/ ArrayRef(const SmallVectorTemplateCommon &Vec) - : Data(Vec.data()), Length(Vec.size()) { - } - - /// Construct an ArrayRef from a std::vector. - template - /*implicit*/ ArrayRef(const std::vector &Vec) - : Data(Vec.data()), Length(Vec.size()) {} - - /// Construct an ArrayRef from a C array. - template - /*implicit*/ LLVM_CONSTEXPR ArrayRef(const T (&Arr)[N]) - : Data(Arr), Length(N) {} - - /// Construct an ArrayRef from a std::initializer_list. - /*implicit*/ ArrayRef(const std::initializer_list &Vec) - : Data(Vec.begin() == Vec.end() ? (T*)nullptr : Vec.begin()), - Length(Vec.size()) {} - - /// Construct an ArrayRef from ArrayRef. This uses SFINAE to - /// ensure that only ArrayRefs of pointers can be converted. - template - ArrayRef( - const ArrayRef &A, - typename std::enable_if< - std::is_convertible::value>::type * = nullptr) - : Data(A.data()), Length(A.size()) {} - - /// Construct an ArrayRef from a SmallVector. This is - /// templated in order to avoid instantiating SmallVectorTemplateCommon - /// whenever we copy-construct an ArrayRef. - template - /*implicit*/ ArrayRef( - const SmallVectorTemplateCommon &Vec, - typename std::enable_if< - std::is_convertible::value>::type * = nullptr) - : Data(Vec.data()), Length(Vec.size()) { - } - - /// Construct an ArrayRef from std::vector. This uses SFINAE - /// to ensure that only vectors of pointers can be converted. - template - ArrayRef(const std::vector &Vec, - typename std::enable_if< - std::is_convertible::value>::type* = 0) - : Data(Vec.data()), Length(Vec.size()) {} - - /// @} - /// @name Simple Operations - /// @{ - - iterator begin() const { return Data; } - iterator end() const { return Data + Length; } - - reverse_iterator rbegin() const { return reverse_iterator(end()); } - reverse_iterator rend() const { return reverse_iterator(begin()); } - - /// empty - Check if the array is empty. - bool empty() const { return Length == 0; } - - const T *data() const { return Data; } - - /// size - Get the array size. - size_t size() const { return Length; } - - /// front - Get the first element. - const T &front() const { - assert(!empty()); - return Data[0]; - } - - /// back - Get the last element. - const T &back() const { - assert(!empty()); - return Data[Length-1]; - } - - // copy - Allocate copy in Allocator and return ArrayRef to it. - template ArrayRef copy(Allocator &A) { - T *Buff = A.template Allocate(Length); - std::uninitialized_copy(begin(), end(), Buff); - return ArrayRef(Buff, Length); - } - - /// equals - Check for element-wise equality. - bool equals(ArrayRef RHS) const { - if (Length != RHS.Length) - return false; - return std::equal(begin(), end(), RHS.begin()); - } - - /// slice(n) - Chop off the first N elements of the array. - ArrayRef slice(size_t N) const { - assert(N <= size() && "Invalid specifier"); - return ArrayRef(data()+N, size()-N); - } - - /// slice(n, m) - Chop off the first N elements of the array, and keep M - /// elements in the array. - ArrayRef slice(size_t N, size_t M) const { - assert(N+M <= size() && "Invalid specifier"); - return ArrayRef(data()+N, M); - } - - /// \brief Drop the first \p N elements of the array. - ArrayRef drop_front(size_t N = 1) const { - assert(size() >= N && "Dropping more elements than exist"); - return slice(N, size() - N); - } - - /// \brief Drop the last \p N elements of the array. - ArrayRef drop_back(size_t N = 1) const { - assert(size() >= N && "Dropping more elements than exist"); - return slice(0, size() - N); - } - - /// @} - /// @name Operator Overloads - /// @{ - const T &operator[](size_t Index) const { - assert(Index < Length && "Invalid index!"); - return Data[Index]; - } - - /// @} - /// @name Expensive Operations - /// @{ - std::vector vec() const { - return std::vector(Data, Data+Length); - } - - /// @} - /// @name Conversion operators - /// @{ - operator std::vector() const { - return std::vector(Data, Data+Length); - } - - /// @} - }; - - /// MutableArrayRef - Represent a mutable reference to an array (0 or more - /// elements consecutively in memory), i.e. a start pointer and a length. It - /// allows various APIs to take and modify consecutive elements easily and - /// conveniently. - /// - /// This class does not own the underlying data, it is expected to be used in - /// situations where the data resides in some other buffer, whose lifetime - /// extends past that of the MutableArrayRef. For this reason, it is not in - /// general safe to store a MutableArrayRef. - /// - /// This is intended to be trivially copyable, so it should be passed by - /// value. - template - class MutableArrayRef : public ArrayRef { - public: - typedef T *iterator; - - typedef std::reverse_iterator reverse_iterator; - - /// Construct an empty MutableArrayRef. - /*implicit*/ MutableArrayRef() : ArrayRef() {} - - /// Construct an empty MutableArrayRef from None. - /*implicit*/ MutableArrayRef(NoneType) : ArrayRef() {} - - /// Construct an MutableArrayRef from a single element. - /*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef(OneElt) {} - - /// Construct an MutableArrayRef from a pointer and length. - /*implicit*/ MutableArrayRef(T *data, size_t length) - : ArrayRef(data, length) {} - - /// Construct an MutableArrayRef from a range. - MutableArrayRef(T *begin, T *end) : ArrayRef(begin, end) {} - - /// Construct an MutableArrayRef from a SmallVector. - /*implicit*/ MutableArrayRef(SmallVectorImpl &Vec) - : ArrayRef(Vec) {} - - /// Construct a MutableArrayRef from a std::vector. - /*implicit*/ MutableArrayRef(std::vector &Vec) - : ArrayRef(Vec) {} - - /// Construct an MutableArrayRef from a C array. - template - /*implicit*/ LLVM_CONSTEXPR MutableArrayRef(T (&Arr)[N]) - : ArrayRef(Arr) {} - - T *data() const { return const_cast(ArrayRef::data()); } - - iterator begin() const { return data(); } - iterator end() const { return data() + this->size(); } - - reverse_iterator rbegin() const { return reverse_iterator(end()); } - reverse_iterator rend() const { return reverse_iterator(begin()); } - - /// front - Get the first element. - T &front() const { - assert(!this->empty()); - return data()[0]; - } - - /// back - Get the last element. - T &back() const { - assert(!this->empty()); - return data()[this->size()-1]; - } - - /// slice(n) - Chop off the first N elements of the array. - MutableArrayRef slice(size_t N) const { - assert(N <= this->size() && "Invalid specifier"); - return MutableArrayRef(data()+N, this->size()-N); - } - - /// slice(n, m) - Chop off the first N elements of the array, and keep M - /// elements in the array. - MutableArrayRef slice(size_t N, size_t M) const { - assert(N+M <= this->size() && "Invalid specifier"); - return MutableArrayRef(data()+N, M); - } - - /// \brief Drop the first \p N elements of the array. - MutableArrayRef drop_front(size_t N = 1) const { - assert(this->size() >= N && "Dropping more elements than exist"); - return slice(N, this->size() - N); - } - - MutableArrayRef drop_back(size_t N = 1) const { - assert(this->size() >= N && "Dropping more elements than exist"); - return slice(0, this->size() - N); - } - - /// @} - /// @name Operator Overloads - /// @{ - T &operator[](size_t Index) const { - assert(Index < this->size() && "Invalid index!"); - return data()[Index]; - } - }; - - /// @name ArrayRef Convenience constructors - /// @{ - - /// Construct an ArrayRef from a single element. - template - ArrayRef makeArrayRef(const T &OneElt) { - return OneElt; - } - - /// Construct an ArrayRef from a pointer and length. - template - ArrayRef makeArrayRef(const T *data, size_t length) { - return ArrayRef(data, length); - } - - /// Construct an ArrayRef from a range. - template - ArrayRef makeArrayRef(const T *begin, const T *end) { - return ArrayRef(begin, end); - } - - /// Construct an ArrayRef from a SmallVector. - template - ArrayRef makeArrayRef(const SmallVectorImpl &Vec) { - return Vec; - } - - /// Construct an ArrayRef from a SmallVector. - template - ArrayRef makeArrayRef(const SmallVector &Vec) { - return Vec; - } - - /// Construct an ArrayRef from a std::vector. - template - ArrayRef makeArrayRef(const std::vector &Vec) { - return Vec; - } - - /// Construct an ArrayRef from an ArrayRef (no-op) (const) - template ArrayRef makeArrayRef(const ArrayRef &Vec) { - return Vec; - } - - /// Construct an ArrayRef from an ArrayRef (no-op) - template ArrayRef &makeArrayRef(ArrayRef &Vec) { - return Vec; - } - - /// Construct an ArrayRef from a C array. - template - ArrayRef makeArrayRef(const T (&Arr)[N]) { - return ArrayRef(Arr); - } - - /// @} - /// @name ArrayRef Comparison Operators - /// @{ - - template - inline bool operator==(ArrayRef LHS, ArrayRef RHS) { - return LHS.equals(RHS); - } - - template - inline bool operator!=(ArrayRef LHS, ArrayRef RHS) { - return !(LHS == RHS); - } - - /// @} - - // ArrayRefs can be treated like a POD type. - template struct isPodLike; - template struct isPodLike > { - static const bool value = true; - }; - - template hash_code hash_value(ArrayRef S) { - return hash_combine_range(S.begin(), S.end()); - } -} // end namespace llvm - -#endif // LLVM_ADT_ARRAYREF_H diff --git a/wpiutil/include/llvm/Compiler.h b/wpiutil/include/llvm/Compiler.h deleted file mode 100644 index b7add94..0000000 --- a/wpiutil/include/llvm/Compiler.h +++ /dev/null @@ -1,92 +0,0 @@ -//===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines several macros, based on the current compiler. This allows -// use of compiler-specific features in a way that remains portable. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_COMPILER_H -#define LLVM_SUPPORT_COMPILER_H - -#ifndef __has_feature -# define __has_feature(x) 0 -#endif - -#ifndef __has_extension -# define __has_extension(x) 0 -#endif - -#ifndef __has_attribute -# define __has_attribute(x) 0 -#endif - -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - -/// \macro LLVM_GNUC_PREREQ -/// \brief Extend the default __GNUC_PREREQ even if glibc's features.h isn't -/// available. -#ifndef LLVM_GNUC_PREREQ -# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) -# define LLVM_GNUC_PREREQ(maj, min, patch) \ - ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \ - ((maj) << 20) + ((min) << 10) + (patch)) -# elif defined(__GNUC__) && defined(__GNUC_MINOR__) -# define LLVM_GNUC_PREREQ(maj, min, patch) \ - ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10)) -# else -# define LLVM_GNUC_PREREQ(maj, min, patch) 0 -# endif -#endif - -#ifndef LLVM_CONSTEXPR -# ifdef _MSC_VER -# if _MSC_VER >= 1900 -# define LLVM_CONSTEXPR constexpr -# else -# define LLVM_CONSTEXPR -# endif -# elif defined(__has_feature) -# if __has_feature(cxx_constexpr) -# define LLVM_CONSTEXPR constexpr -# else -# define LLVM_CONSTEXPR -# endif -# elif defined(__GXX_EXPERIMENTAL_CXX0X__) -# define LLVM_CONSTEXPR constexpr -# elif defined(__has_constexpr) -# define LLVM_CONSTEXPR constexpr -# else -# define LLVM_CONSTEXPR -# endif -#endif - -#ifndef LLVM_ATTRIBUTE_UNUSED_RESULT -#if __has_attribute(warn_unused_result) || LLVM_GNUC_PREREQ(3, 4, 0) -#define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__)) -#elif defined(_MSC_VER) -#define LLVM_ATTRIBUTE_UNUSED_RESULT _Check_return_ -#else -#define LLVM_ATTRIBUTE_UNUSED_RESULT -#endif -#endif - -#ifndef LLVM_UNLIKELY -#if __has_builtin(__builtin_expect) || LLVM_GNUC_PREREQ(4, 0, 0) -#define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) -#define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) -#else -#define LLVM_LIKELY(EXPR) (EXPR) -#define LLVM_UNLIKELY(EXPR) (EXPR) -#endif -#endif - -#endif diff --git a/wpiutil/include/llvm/ConvertUTF.h b/wpiutil/include/llvm/ConvertUTF.h deleted file mode 100644 index 5b02533..0000000 --- a/wpiutil/include/llvm/ConvertUTF.h +++ /dev/null @@ -1,255 +0,0 @@ -/*===--- ConvertUTF.h - Universal Character Names conversions ---------------=== - * - * The LLVM Compiler Infrastructure - * - * This file is distributed under the University of Illinois Open Source - * License. See LICENSE.TXT for details. - * - *==------------------------------------------------------------------------==*/ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Header file. - - Several funtions are included here, forming a complete set of - conversions between the three formats. UTF-7 is not included - here, but is handled in a separate source file. - - Each of these routines takes pointers to input buffers and output - buffers. The input buffers are const. - - Each routine converts the text between *sourceStart and sourceEnd, - putting the result into the buffer between *targetStart and - targetEnd. Note: the end pointers are *after* the last item: e.g. - *(sourceEnd - 1) is the last item. - - The return result indicates whether the conversion was successful, - and if not, whether the problem was in the source or target buffers. - (Only the first encountered problem is indicated.) - - After the conversion, *sourceStart and *targetStart are both - updated to point to the end of last text successfully converted in - the respective buffers. - - Input parameters: - sourceStart - pointer to a pointer to the source buffer. - The contents of this are modified on return so that - it points at the next thing to be converted. - targetStart - similarly, pointer to pointer to the target buffer. - sourceEnd, targetEnd - respectively pointers to the ends of the - two buffers, for overflow checking only. - - These conversion functions take a ConversionFlags argument. When this - flag is set to strict, both irregular sequences and isolated surrogates - will cause an error. When the flag is set to lenient, both irregular - sequences and isolated surrogates are converted. - - Whether the flag is strict or lenient, all illegal sequences will cause - an error return. This includes sequences such as: , , - or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code - must check for illegal sequences. - - When the flag is set to lenient, characters over 0x10FFFF are converted - to the replacement character; otherwise (when the flag is set to strict) - they constitute an error. - - Output parameters: - The value "sourceIllegal" is returned from some routines if the input - sequence is malformed. When "sourceIllegal" is returned, the source - value will point to the illegal value that caused the problem. E.g., - in UTF-8 when a sequence is malformed, it points to the start of the - malformed sequence. - - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Fixes & updates, Sept 2001. - ------------------------------------------------------------------------- */ - -#ifndef LLVM_SUPPORT_CONVERTUTF_H -#define LLVM_SUPPORT_CONVERTUTF_H - -/* --------------------------------------------------------------------- - The following 4 definitions are compiler-specific. - The C standard does not guarantee that wchar_t has at least - 16 bits, so wchar_t is no less portable than unsigned short! - All should be unsigned values to avoid sign extension during - bit mask & shift operations. ------------------------------------------------------------------------- */ - -typedef unsigned int UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ -typedef bool Boolean; /* 0 or 1 */ - -/* Some fundamental constants */ -#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD -#define UNI_MAX_BMP (UTF32)0x0000FFFF -#define UNI_MAX_UTF16 (UTF32)0x0010FFFF -#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF -#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF - -#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4 - -#define UNI_UTF16_BYTE_ORDER_MARK_NATIVE 0xFEFF -#define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE - -typedef enum { - conversionOK, /* conversion successful */ - sourceExhausted, /* partial character in source, but hit end */ - targetExhausted, /* insuff. room in target for conversion */ - sourceIllegal /* source sequence is illegal/malformed */ -} ConversionResult; - -typedef enum { - strictConversion = 0, - lenientConversion -} ConversionFlags; - -/* This is for C++ and does no harm in C */ -#ifdef __cplusplus -extern "C" { -#endif - -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -/** - * Convert a partial UTF8 sequence to UTF32. If the sequence ends in an - * incomplete code unit sequence, returns \c sourceExhausted. - */ -ConversionResult ConvertUTF8toUTF32Partial( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -/** - * Convert a partial UTF8 sequence to UTF32. If the sequence ends in an - * incomplete code unit sequence, returns \c sourceIllegal. - */ -ConversionResult ConvertUTF8toUTF32( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); - -Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd); - -unsigned getNumBytesForUTF8(UTF8 firstByte); - -#ifdef __cplusplus -} - -/*************************************************************************/ -/* Below are LLVM-specific wrappers of the functions above. */ - -#include "llvm/ArrayRef.h" -#include "llvm/StringRef.h" - -namespace llvm { - -/** - * Convert an Unicode code point to UTF8 sequence. - * - * \param Source a Unicode code point. - * \param [in,out] ResultPtr pointer to the output buffer, needs to be at least - * \c UNI_MAX_UTF8_BYTES_PER_CODE_POINT bytes. On success \c ResultPtr is - * updated one past end of the converted sequence. - * - * \returns true on success. - */ -bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr); - -/** - * Convert the first UTF8 sequence in the given source buffer to a UTF32 - * code point. - * - * \param [in,out] source A pointer to the source buffer. If the conversion - * succeeds, this pointer will be updated to point to the byte just past the - * end of the converted sequence. - * \param sourceEnd A pointer just past the end of the source buffer. - * \param [out] target The converted code - * \param flags Whether the conversion is strict or lenient. - * - * \returns conversionOK on success - * - * \sa ConvertUTF8toUTF32 - */ -static inline ConversionResult convertUTF8Sequence(const UTF8 **source, - const UTF8 *sourceEnd, - UTF32 *target, - ConversionFlags flags) { - if (*source == sourceEnd) - return sourceExhausted; - unsigned size = getNumBytesForUTF8(**source); - if ((ptrdiff_t)size > sourceEnd - *source) - return sourceExhausted; - return ConvertUTF8toUTF32(source, *source + size, &target, target + 1, flags); -} - -/** - * Returns true if a blob of text starts with a UTF-16 big or little endian byte - * order mark. - */ -bool hasUTF16ByteOrderMark(ArrayRef SrcBytes); - -/** - * Converts a UTF-16 string into a UTF-8 string. - * - * \returns true on success - */ -bool convertUTF16ToUTF8String(ArrayRef SrcUTF16, - SmallVectorImpl &DstUTF8); - -/** - * Converts a UTF-8 string into a UTF-16 string with native endianness. - * - * \returns true on success - */ -bool convertUTF8ToUTF16String(StringRef SrcUTF8, - SmallVectorImpl &DstUTF16); - -} /* end namespace llvm */ - -#endif - -/* --------------------------------------------------------------------- */ - -#endif diff --git a/wpiutil/include/llvm/DenseMap.h b/wpiutil/include/llvm/DenseMap.h deleted file mode 100644 index 6b66d7e..0000000 --- a/wpiutil/include/llvm/DenseMap.h +++ /dev/null @@ -1,1120 +0,0 @@ -//===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the DenseMap class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_DENSEMAP_H -#define LLVM_ADT_DENSEMAP_H - -#include "llvm/DenseMapInfo.h" -#include "llvm/EpochTracker.h" -#include "llvm/AlignOf.h" -#include "llvm/Compiler.h" -#include "llvm/MathExtras.h" -#include "llvm/PointerLikeTypeTraits.h" -#include "llvm/type_traits.h" -#include -#include -#include -#include -#include -#include -#include -#include - -namespace llvm { - -namespace detail { -// We extend a pair to allow users to override the bucket type with their own -// implementation without requiring two members. -template -struct DenseMapPair : public std::pair { - KeyT &getFirst() { return std::pair::first; } - const KeyT &getFirst() const { return std::pair::first; } - ValueT &getSecond() { return std::pair::second; } - const ValueT &getSecond() const { return std::pair::second; } -}; -} - -template < - typename KeyT, typename ValueT, typename KeyInfoT = DenseMapInfo, - typename Bucket = detail::DenseMapPair, bool IsConst = false> -class DenseMapIterator; - -template -class DenseMapBase : public DebugEpochBase { -public: - typedef unsigned size_type; - typedef KeyT key_type; - typedef ValueT mapped_type; - typedef BucketT value_type; - - typedef DenseMapIterator iterator; - typedef DenseMapIterator - const_iterator; - inline iterator begin() { - // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets(). - return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this); - } - inline iterator end() { - return iterator(getBucketsEnd(), getBucketsEnd(), *this, true); - } - inline const_iterator begin() const { - return empty() ? end() - : const_iterator(getBuckets(), getBucketsEnd(), *this); - } - inline const_iterator end() const { - return const_iterator(getBucketsEnd(), getBucketsEnd(), *this, true); - } - - bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { - return getNumEntries() == 0; - } - unsigned size() const { return getNumEntries(); } - - /// Grow the densemap so that it can contain at least \p NumEntries items - /// before resizing again. - void reserve(size_type NumEntries) { - auto NumBuckets = getMinBucketToReserveForEntries(NumEntries); - incrementEpoch(); - if (NumBuckets > getNumBuckets()) - grow(NumBuckets); - } - - void clear() { - incrementEpoch(); - if (getNumEntries() == 0 && getNumTombstones() == 0) return; - - // If the capacity of the array is huge, and the # elements used is small, - // shrink the array. - if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) { - shrink_and_clear(); - return; - } - - const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); - unsigned NumEntries = getNumEntries(); - for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { - if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) { - if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) { - P->getSecond().~ValueT(); - --NumEntries; - } - P->getFirst() = EmptyKey; - } - } - assert(NumEntries == 0 && "Node count imbalance!"); - setNumEntries(0); - setNumTombstones(0); - } - - /// Return 1 if the specified key is in the map, 0 otherwise. - size_type count(const KeyT &Val) const { - const BucketT *TheBucket; - return LookupBucketFor(Val, TheBucket) ? 1 : 0; - } - - iterator find(const KeyT &Val) { - BucketT *TheBucket; - if (LookupBucketFor(Val, TheBucket)) - return iterator(TheBucket, getBucketsEnd(), *this, true); - return end(); - } - const_iterator find(const KeyT &Val) const { - const BucketT *TheBucket; - if (LookupBucketFor(Val, TheBucket)) - return const_iterator(TheBucket, getBucketsEnd(), *this, true); - return end(); - } - - /// Alternate version of find() which allows a different, and possibly - /// less expensive, key type. - /// The DenseMapInfo is responsible for supplying methods - /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key - /// type used. - template - iterator find_as(const LookupKeyT &Val) { - BucketT *TheBucket; - if (LookupBucketFor(Val, TheBucket)) - return iterator(TheBucket, getBucketsEnd(), *this, true); - return end(); - } - template - const_iterator find_as(const LookupKeyT &Val) const { - const BucketT *TheBucket; - if (LookupBucketFor(Val, TheBucket)) - return const_iterator(TheBucket, getBucketsEnd(), *this, true); - return end(); - } - - /// lookup - Return the entry for the specified key, or a default - /// constructed value if no such entry exists. - ValueT lookup(const KeyT &Val) const { - const BucketT *TheBucket; - if (LookupBucketFor(Val, TheBucket)) - return TheBucket->getSecond(); - return ValueT(); - } - - // Inserts key,value pair into the map if the key isn't already in the map. - // If the key is already in the map, it returns false and doesn't update the - // value. - std::pair insert(const std::pair &KV) { - BucketT *TheBucket; - if (LookupBucketFor(KV.first, TheBucket)) - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - false); // Already in map. - - // Otherwise, insert the new element. - TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket); - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - true); - } - - // Inserts key,value pair into the map if the key isn't already in the map. - // If the key is already in the map, it returns false and doesn't update the - // value. - std::pair insert(std::pair &&KV) { - BucketT *TheBucket; - if (LookupBucketFor(KV.first, TheBucket)) - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - false); // Already in map. - - // Otherwise, insert the new element. - TheBucket = InsertIntoBucket(std::move(KV.first), - std::move(KV.second), - TheBucket); - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - true); - } - - /// Alternate version of insert() which allows a different, and possibly - /// less expensive, key type. - /// The DenseMapInfo is responsible for supplying methods - /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key - /// type used. - template - std::pair insert_as(std::pair &&KV, - const LookupKeyT &Val) { - BucketT *TheBucket; - if (LookupBucketFor(Val, TheBucket)) - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - false); // Already in map. - - // Otherwise, insert the new element. - TheBucket = InsertIntoBucket(std::move(KV.first), std::move(KV.second), Val, - TheBucket); - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - true); - } - - /// insert - Range insertion of pairs. - template - void insert(InputIt I, InputIt E) { - for (; I != E; ++I) - insert(*I); - } - - - bool erase(const KeyT &Val) { - BucketT *TheBucket; - if (!LookupBucketFor(Val, TheBucket)) - return false; // not in map. - - TheBucket->getSecond().~ValueT(); - TheBucket->getFirst() = getTombstoneKey(); - decrementNumEntries(); - incrementNumTombstones(); - return true; - } - void erase(iterator I) { - BucketT *TheBucket = &*I; - TheBucket->getSecond().~ValueT(); - TheBucket->getFirst() = getTombstoneKey(); - decrementNumEntries(); - incrementNumTombstones(); - } - - value_type& FindAndConstruct(const KeyT &Key) { - BucketT *TheBucket; - if (LookupBucketFor(Key, TheBucket)) - return *TheBucket; - - return *InsertIntoBucket(Key, ValueT(), TheBucket); - } - - ValueT &operator[](const KeyT &Key) { - return FindAndConstruct(Key).second; - } - - value_type& FindAndConstruct(KeyT &&Key) { - BucketT *TheBucket; - if (LookupBucketFor(Key, TheBucket)) - return *TheBucket; - - return *InsertIntoBucket(std::move(Key), ValueT(), TheBucket); - } - - ValueT &operator[](KeyT &&Key) { - return FindAndConstruct(std::move(Key)).second; - } - - /// isPointerIntoBucketsArray - Return true if the specified pointer points - /// somewhere into the DenseMap's array of buckets (i.e. either to a key or - /// value in the DenseMap). - bool isPointerIntoBucketsArray(const void *Ptr) const { - return Ptr >= getBuckets() && Ptr < getBucketsEnd(); - } - - /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets - /// array. In conjunction with the previous method, this can be used to - /// determine whether an insertion caused the DenseMap to reallocate. - const void *getPointerIntoBucketsArray() const { return getBuckets(); } - -protected: - DenseMapBase() = default; - - void destroyAll() { - if (getNumBuckets() == 0) // Nothing to do. - return; - - const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); - for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { - if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) && - !KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) - P->getSecond().~ValueT(); - P->getFirst().~KeyT(); - } - } - - void initEmpty() { - setNumEntries(0); - setNumTombstones(0); - - assert((getNumBuckets() & (getNumBuckets()-1)) == 0 && - "# initial buckets must be a power of two!"); - const KeyT EmptyKey = getEmptyKey(); - for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B) - ::new (&B->getFirst()) KeyT(EmptyKey); - } - - /// Returns the number of buckets to allocate to ensure that the DenseMap can - /// accommodate \p NumEntries without need to grow(). - unsigned getMinBucketToReserveForEntries(unsigned NumEntries) { - // Ensure that "NumEntries * 4 < NumBuckets * 3" - if (NumEntries == 0) - return 0; - // +1 is required because of the strict equality. - // For example if NumEntries is 48, we need to return 401. - return NextPowerOf2(NumEntries * 4 / 3 + 1); - } - - void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) { - initEmpty(); - - // Insert all the old elements. - const KeyT EmptyKey = getEmptyKey(); - const KeyT TombstoneKey = getTombstoneKey(); - for (BucketT *B = OldBucketsBegin, *E = OldBucketsEnd; B != E; ++B) { - if (!KeyInfoT::isEqual(B->getFirst(), EmptyKey) && - !KeyInfoT::isEqual(B->getFirst(), TombstoneKey)) { - // Insert the key/value into the new table. - BucketT *DestBucket; - bool FoundVal = LookupBucketFor(B->getFirst(), DestBucket); - (void)FoundVal; // silence warning. - assert(!FoundVal && "Key already in new map?"); - DestBucket->getFirst() = std::move(B->getFirst()); - ::new (&DestBucket->getSecond()) ValueT(std::move(B->getSecond())); - incrementNumEntries(); - - // Free the value. - B->getSecond().~ValueT(); - } - B->getFirst().~KeyT(); - } - } - - template - void copyFrom( - const DenseMapBase &other) { - assert(&other != this); - assert(getNumBuckets() == other.getNumBuckets()); - - setNumEntries(other.getNumEntries()); - setNumTombstones(other.getNumTombstones()); - - if (isPodLike::value && isPodLike::value) - memcpy(getBuckets(), other.getBuckets(), - getNumBuckets() * sizeof(BucketT)); - else - for (size_t i = 0; i < getNumBuckets(); ++i) { - ::new (&getBuckets()[i].getFirst()) - KeyT(other.getBuckets()[i].getFirst()); - if (!KeyInfoT::isEqual(getBuckets()[i].getFirst(), getEmptyKey()) && - !KeyInfoT::isEqual(getBuckets()[i].getFirst(), getTombstoneKey())) - ::new (&getBuckets()[i].getSecond()) - ValueT(other.getBuckets()[i].getSecond()); - } - } - - static unsigned getHashValue(const KeyT &Val) { - return KeyInfoT::getHashValue(Val); - } - template - static unsigned getHashValue(const LookupKeyT &Val) { - return KeyInfoT::getHashValue(Val); - } - static const KeyT getEmptyKey() { - return KeyInfoT::getEmptyKey(); - } - static const KeyT getTombstoneKey() { - return KeyInfoT::getTombstoneKey(); - } - -private: - unsigned getNumEntries() const { - return static_cast(this)->getNumEntries(); - } - void setNumEntries(unsigned Num) { - static_cast(this)->setNumEntries(Num); - } - void incrementNumEntries() { - setNumEntries(getNumEntries() + 1); - } - void decrementNumEntries() { - setNumEntries(getNumEntries() - 1); - } - unsigned getNumTombstones() const { - return static_cast(this)->getNumTombstones(); - } - void setNumTombstones(unsigned Num) { - static_cast(this)->setNumTombstones(Num); - } - void incrementNumTombstones() { - setNumTombstones(getNumTombstones() + 1); - } - void decrementNumTombstones() { - setNumTombstones(getNumTombstones() - 1); - } - const BucketT *getBuckets() const { - return static_cast(this)->getBuckets(); - } - BucketT *getBuckets() { - return static_cast(this)->getBuckets(); - } - unsigned getNumBuckets() const { - return static_cast(this)->getNumBuckets(); - } - BucketT *getBucketsEnd() { - return getBuckets() + getNumBuckets(); - } - const BucketT *getBucketsEnd() const { - return getBuckets() + getNumBuckets(); - } - - void grow(unsigned AtLeast) { - static_cast(this)->grow(AtLeast); - } - - void shrink_and_clear() { - static_cast(this)->shrink_and_clear(); - } - - - BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value, - BucketT *TheBucket) { - TheBucket = InsertIntoBucketImpl(Key, Key, TheBucket); - - TheBucket->getFirst() = Key; - ::new (&TheBucket->getSecond()) ValueT(Value); - return TheBucket; - } - - BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value, - BucketT *TheBucket) { - TheBucket = InsertIntoBucketImpl(Key, Key, TheBucket); - - TheBucket->getFirst() = Key; - ::new (&TheBucket->getSecond()) ValueT(std::move(Value)); - return TheBucket; - } - - BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT *TheBucket) { - TheBucket = InsertIntoBucketImpl(Key, Key, TheBucket); - - TheBucket->getFirst() = std::move(Key); - ::new (&TheBucket->getSecond()) ValueT(std::move(Value)); - return TheBucket; - } - - template - BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, LookupKeyT &Lookup, - BucketT *TheBucket) { - TheBucket = InsertIntoBucketImpl(Key, Lookup, TheBucket); - - TheBucket->getFirst() = std::move(Key); - ::new (&TheBucket->getSecond()) ValueT(std::move(Value)); - return TheBucket; - } - - template - BucketT *InsertIntoBucketImpl(const KeyT &Key, const LookupKeyT &Lookup, - BucketT *TheBucket) { - incrementEpoch(); - - // If the load of the hash table is more than 3/4, or if fewer than 1/8 of - // the buckets are empty (meaning that many are filled with tombstones), - // grow the table. - // - // The later case is tricky. For example, if we had one empty bucket with - // tons of tombstones, failing lookups (e.g. for insertion) would have to - // probe almost the entire table until it found the empty bucket. If the - // table completely filled with tombstones, no lookup would ever succeed, - // causing infinite loops in lookup. - unsigned NewNumEntries = getNumEntries() + 1; - unsigned NumBuckets = getNumBuckets(); - if (LLVM_UNLIKELY(NewNumEntries * 4 >= NumBuckets * 3)) { - this->grow(NumBuckets * 2); - LookupBucketFor(Lookup, TheBucket); - NumBuckets = getNumBuckets(); - } else if (LLVM_UNLIKELY(NumBuckets-(NewNumEntries+getNumTombstones()) <= - NumBuckets/8)) { - this->grow(NumBuckets); - LookupBucketFor(Lookup, TheBucket); - } - assert(TheBucket); - - // Only update the state after we've grown our bucket space appropriately - // so that when growing buckets we have self-consistent entry count. - incrementNumEntries(); - - // If we are writing over a tombstone, remember this. - const KeyT EmptyKey = getEmptyKey(); - if (!KeyInfoT::isEqual(TheBucket->getFirst(), EmptyKey)) - decrementNumTombstones(); - - return TheBucket; - } - - /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in - /// FoundBucket. If the bucket contains the key and a value, this returns - /// true, otherwise it returns a bucket with an empty marker or tombstone and - /// returns false. - template - bool LookupBucketFor(const LookupKeyT &Val, - const BucketT *&FoundBucket) const { - const BucketT *BucketsPtr = getBuckets(); - const unsigned NumBuckets = getNumBuckets(); - - if (NumBuckets == 0) { - FoundBucket = nullptr; - return false; - } - - // FoundTombstone - Keep track of whether we find a tombstone while probing. - const BucketT *FoundTombstone = nullptr; - const KeyT EmptyKey = getEmptyKey(); - const KeyT TombstoneKey = getTombstoneKey(); - assert(!KeyInfoT::isEqual(Val, EmptyKey) && - !KeyInfoT::isEqual(Val, TombstoneKey) && - "Empty/Tombstone value shouldn't be inserted into map!"); - - unsigned BucketNo = getHashValue(Val) & (NumBuckets-1); - unsigned ProbeAmt = 1; - while (1) { - const BucketT *ThisBucket = BucketsPtr + BucketNo; - // Found Val's bucket? If so, return it. - if (LLVM_LIKELY(KeyInfoT::isEqual(Val, ThisBucket->getFirst()))) { - FoundBucket = ThisBucket; - return true; - } - - // If we found an empty bucket, the key doesn't exist in the set. - // Insert it and return the default value. - if (LLVM_LIKELY(KeyInfoT::isEqual(ThisBucket->getFirst(), EmptyKey))) { - // If we've already seen a tombstone while probing, fill it in instead - // of the empty bucket we eventually probed to. - FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket; - return false; - } - - // If this is a tombstone, remember it. If Val ends up not in the map, we - // prefer to return it than something that would require more probing. - if (KeyInfoT::isEqual(ThisBucket->getFirst(), TombstoneKey) && - !FoundTombstone) - FoundTombstone = ThisBucket; // Remember the first tombstone found. - - // Otherwise, it's a hash collision or a tombstone, continue quadratic - // probing. - BucketNo += ProbeAmt++; - BucketNo &= (NumBuckets-1); - } - } - - template - bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) { - const BucketT *ConstFoundBucket; - bool Result = const_cast(this) - ->LookupBucketFor(Val, ConstFoundBucket); - FoundBucket = const_cast(ConstFoundBucket); - return Result; - } - -public: - /// Return the approximate size (in bytes) of the actual map. - /// This is just the raw memory used by DenseMap. - /// If entries are pointers to objects, the size of the referenced objects - /// are not included. - size_t getMemorySize() const { - return getNumBuckets() * sizeof(BucketT); - } -}; - -template , - typename BucketT = detail::DenseMapPair> -class DenseMap : public DenseMapBase, - KeyT, ValueT, KeyInfoT, BucketT> { - // Lift some types from the dependent base class into this class for - // simplicity of referring to them. - typedef DenseMapBase BaseT; - friend class DenseMapBase; - - BucketT *Buckets; - unsigned NumEntries; - unsigned NumTombstones; - unsigned NumBuckets; - -public: - /// Create a DenseMap wth an optional \p InitialReserve that guarantee that - /// this number of elements can be inserted in the map without grow() - explicit DenseMap(unsigned InitialReserve = 0) { init(InitialReserve); } - - DenseMap(const DenseMap &other) : BaseT() { - init(0); - copyFrom(other); - } - - DenseMap(DenseMap &&other) : BaseT() { - init(0); - swap(other); - } - - template - DenseMap(const InputIt &I, const InputIt &E) { - init(std::distance(I, E)); - this->insert(I, E); - } - - ~DenseMap() { - this->destroyAll(); - operator delete(Buckets); - } - - void swap(DenseMap& RHS) { - this->incrementEpoch(); - RHS.incrementEpoch(); - std::swap(Buckets, RHS.Buckets); - std::swap(NumEntries, RHS.NumEntries); - std::swap(NumTombstones, RHS.NumTombstones); - std::swap(NumBuckets, RHS.NumBuckets); - } - - DenseMap& operator=(const DenseMap& other) { - if (&other != this) - copyFrom(other); - return *this; - } - - DenseMap& operator=(DenseMap &&other) { - this->destroyAll(); - operator delete(Buckets); - init(0); - swap(other); - return *this; - } - - void copyFrom(const DenseMap& other) { - this->destroyAll(); - operator delete(Buckets); - if (allocateBuckets(other.NumBuckets)) { - this->BaseT::copyFrom(other); - } else { - NumEntries = 0; - NumTombstones = 0; - } - } - - void init(unsigned InitNumEntries) { - auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries); - if (allocateBuckets(InitBuckets)) { - this->BaseT::initEmpty(); - } else { - NumEntries = 0; - NumTombstones = 0; - } - } - - void grow(unsigned AtLeast) { - unsigned OldNumBuckets = NumBuckets; - BucketT *OldBuckets = Buckets; - - allocateBuckets(std::max(64, static_cast(NextPowerOf2(AtLeast-1)))); - assert(Buckets); - if (!OldBuckets) { - this->BaseT::initEmpty(); - return; - } - - this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets); - - // Free the old table. - operator delete(OldBuckets); - } - - void shrink_and_clear() { - unsigned OldNumEntries = NumEntries; - this->destroyAll(); - - // Reduce the number of buckets. - unsigned NewNumBuckets = 0; - if (OldNumEntries) - NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1)); - if (NewNumBuckets == NumBuckets) { - this->BaseT::initEmpty(); - return; - } - - operator delete(Buckets); - init(NewNumBuckets); - } - -private: - unsigned getNumEntries() const { - return NumEntries; - } - void setNumEntries(unsigned Num) { - NumEntries = Num; - } - - unsigned getNumTombstones() const { - return NumTombstones; - } - void setNumTombstones(unsigned Num) { - NumTombstones = Num; - } - - BucketT *getBuckets() const { - return Buckets; - } - - unsigned getNumBuckets() const { - return NumBuckets; - } - - bool allocateBuckets(unsigned Num) { - NumBuckets = Num; - if (NumBuckets == 0) { - Buckets = nullptr; - return false; - } - - Buckets = static_cast(operator new(sizeof(BucketT) * NumBuckets)); - return true; - } -}; - -template , - typename BucketT = detail::DenseMapPair> -class SmallDenseMap - : public DenseMapBase< - SmallDenseMap, KeyT, - ValueT, KeyInfoT, BucketT> { - // Lift some types from the dependent base class into this class for - // simplicity of referring to them. - typedef DenseMapBase BaseT; - friend class DenseMapBase; - - unsigned Small : 1; - unsigned NumEntries : 31; - unsigned NumTombstones; - - struct LargeRep { - BucketT *Buckets; - unsigned NumBuckets; - }; - - /// A "union" of an inline bucket array and the struct representing - /// a large bucket. This union will be discriminated by the 'Small' bit. - AlignedCharArrayUnion storage; - -public: - explicit SmallDenseMap(unsigned NumInitBuckets = 0) { - init(NumInitBuckets); - } - - SmallDenseMap(const SmallDenseMap &other) : BaseT() { - init(0); - copyFrom(other); - } - - SmallDenseMap(SmallDenseMap &&other) : BaseT() { - init(0); - swap(other); - } - - template - SmallDenseMap(const InputIt &I, const InputIt &E) { - init(NextPowerOf2(std::distance(I, E))); - this->insert(I, E); - } - - ~SmallDenseMap() { - this->destroyAll(); - deallocateBuckets(); - } - - void swap(SmallDenseMap& RHS) { - unsigned TmpNumEntries = RHS.NumEntries; - RHS.NumEntries = NumEntries; - NumEntries = TmpNumEntries; - std::swap(NumTombstones, RHS.NumTombstones); - - const KeyT EmptyKey = this->getEmptyKey(); - const KeyT TombstoneKey = this->getTombstoneKey(); - if (Small && RHS.Small) { - // If we're swapping inline bucket arrays, we have to cope with some of - // the tricky bits of DenseMap's storage system: the buckets are not - // fully initialized. Thus we swap every key, but we may have - // a one-directional move of the value. - for (unsigned i = 0, e = InlineBuckets; i != e; ++i) { - BucketT *LHSB = &getInlineBuckets()[i], - *RHSB = &RHS.getInlineBuckets()[i]; - bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->getFirst(), EmptyKey) && - !KeyInfoT::isEqual(LHSB->getFirst(), TombstoneKey)); - bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->getFirst(), EmptyKey) && - !KeyInfoT::isEqual(RHSB->getFirst(), TombstoneKey)); - if (hasLHSValue && hasRHSValue) { - // Swap together if we can... - std::swap(*LHSB, *RHSB); - continue; - } - // Swap separately and handle any assymetry. - std::swap(LHSB->getFirst(), RHSB->getFirst()); - if (hasLHSValue) { - ::new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond())); - LHSB->getSecond().~ValueT(); - } else if (hasRHSValue) { - ::new (&LHSB->getSecond()) ValueT(std::move(RHSB->getSecond())); - RHSB->getSecond().~ValueT(); - } - } - return; - } - if (!Small && !RHS.Small) { - std::swap(getLargeRep()->Buckets, RHS.getLargeRep()->Buckets); - std::swap(getLargeRep()->NumBuckets, RHS.getLargeRep()->NumBuckets); - return; - } - - SmallDenseMap &SmallSide = Small ? *this : RHS; - SmallDenseMap &LargeSide = Small ? RHS : *this; - - // First stash the large side's rep and move the small side across. - LargeRep TmpRep = std::move(*LargeSide.getLargeRep()); - LargeSide.getLargeRep()->~LargeRep(); - LargeSide.Small = true; - // This is similar to the standard move-from-old-buckets, but the bucket - // count hasn't actually rotated in this case. So we have to carefully - // move construct the keys and values into their new locations, but there - // is no need to re-hash things. - for (unsigned i = 0, e = InlineBuckets; i != e; ++i) { - BucketT *NewB = &LargeSide.getInlineBuckets()[i], - *OldB = &SmallSide.getInlineBuckets()[i]; - ::new (&NewB->getFirst()) KeyT(std::move(OldB->getFirst())); - OldB->getFirst().~KeyT(); - if (!KeyInfoT::isEqual(NewB->getFirst(), EmptyKey) && - !KeyInfoT::isEqual(NewB->getFirst(), TombstoneKey)) { - ::new (&NewB->getSecond()) ValueT(std::move(OldB->getSecond())); - OldB->getSecond().~ValueT(); - } - } - - // The hard part of moving the small buckets across is done, just move - // the TmpRep into its new home. - SmallSide.Small = false; - new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep)); - } - - SmallDenseMap& operator=(const SmallDenseMap& other) { - if (&other != this) - copyFrom(other); - return *this; - } - - SmallDenseMap& operator=(SmallDenseMap &&other) { - this->destroyAll(); - deallocateBuckets(); - init(0); - swap(other); - return *this; - } - - void copyFrom(const SmallDenseMap& other) { - this->destroyAll(); - deallocateBuckets(); - Small = true; - if (other.getNumBuckets() > InlineBuckets) { - Small = false; - new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets())); - } - this->BaseT::copyFrom(other); - } - - void init(unsigned InitBuckets) { - Small = true; - if (InitBuckets > InlineBuckets) { - Small = false; - new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets)); - } - this->BaseT::initEmpty(); - } - - void grow(unsigned AtLeast) { - if (AtLeast >= InlineBuckets) - AtLeast = std::max(64, NextPowerOf2(AtLeast-1)); - - if (Small) { - if (AtLeast < InlineBuckets) - return; // Nothing to do. - - // First move the inline buckets into a temporary storage. - AlignedCharArrayUnion TmpStorage; - BucketT *TmpBegin = reinterpret_cast(TmpStorage.buffer); - BucketT *TmpEnd = TmpBegin; - - // Loop over the buckets, moving non-empty, non-tombstones into the - // temporary storage. Have the loop move the TmpEnd forward as it goes. - const KeyT EmptyKey = this->getEmptyKey(); - const KeyT TombstoneKey = this->getTombstoneKey(); - for (BucketT *P = getBuckets(), *E = P + InlineBuckets; P != E; ++P) { - if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) && - !KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) { - assert(size_t(TmpEnd - TmpBegin) < InlineBuckets && - "Too many inline buckets!"); - ::new (&TmpEnd->getFirst()) KeyT(std::move(P->getFirst())); - ::new (&TmpEnd->getSecond()) ValueT(std::move(P->getSecond())); - ++TmpEnd; - P->getSecond().~ValueT(); - } - P->getFirst().~KeyT(); - } - - // Now make this map use the large rep, and move all the entries back - // into it. - Small = false; - new (getLargeRep()) LargeRep(allocateBuckets(AtLeast)); - this->moveFromOldBuckets(TmpBegin, TmpEnd); - return; - } - - LargeRep OldRep = std::move(*getLargeRep()); - getLargeRep()->~LargeRep(); - if (AtLeast <= InlineBuckets) { - Small = true; - } else { - new (getLargeRep()) LargeRep(allocateBuckets(AtLeast)); - } - - this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets); - - // Free the old table. - operator delete(OldRep.Buckets); - } - - void shrink_and_clear() { - unsigned OldSize = this->size(); - this->destroyAll(); - - // Reduce the number of buckets. - unsigned NewNumBuckets = 0; - if (OldSize) { - NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1); - if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u) - NewNumBuckets = 64; - } - if ((Small && NewNumBuckets <= InlineBuckets) || - (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) { - this->BaseT::initEmpty(); - return; - } - - deallocateBuckets(); - init(NewNumBuckets); - } - -private: - unsigned getNumEntries() const { - return NumEntries; - } - void setNumEntries(unsigned Num) { - assert(Num < INT_MAX && "Cannot support more than INT_MAX entries"); - NumEntries = Num; - } - - unsigned getNumTombstones() const { - return NumTombstones; - } - void setNumTombstones(unsigned Num) { - NumTombstones = Num; - } - - const BucketT *getInlineBuckets() const { - assert(Small); - // Note that this cast does not violate aliasing rules as we assert that - // the memory's dynamic type is the small, inline bucket buffer, and the - // 'storage.buffer' static type is 'char *'. - return reinterpret_cast(storage.buffer); - } - BucketT *getInlineBuckets() { - return const_cast( - const_cast(this)->getInlineBuckets()); - } - const LargeRep *getLargeRep() const { - assert(!Small); - // Note, same rule about aliasing as with getInlineBuckets. - return reinterpret_cast(storage.buffer); - } - LargeRep *getLargeRep() { - return const_cast( - const_cast(this)->getLargeRep()); - } - - const BucketT *getBuckets() const { - return Small ? getInlineBuckets() : getLargeRep()->Buckets; - } - BucketT *getBuckets() { - return const_cast( - const_cast(this)->getBuckets()); - } - unsigned getNumBuckets() const { - return Small ? InlineBuckets : getLargeRep()->NumBuckets; - } - - void deallocateBuckets() { - if (Small) - return; - - operator delete(getLargeRep()->Buckets); - getLargeRep()->~LargeRep(); - } - - LargeRep allocateBuckets(unsigned Num) { - assert(Num > InlineBuckets && "Must allocate more buckets than are inline"); - LargeRep Rep = { - static_cast(operator new(sizeof(BucketT) * Num)), Num - }; - return Rep; - } -}; - -template -class DenseMapIterator : DebugEpochBase::HandleBase { - typedef DenseMapIterator ConstIterator; - friend class DenseMapIterator; - friend class DenseMapIterator; - -public: - typedef ptrdiff_t difference_type; - typedef typename std::conditional::type - value_type; - typedef value_type *pointer; - typedef value_type &reference; - typedef std::forward_iterator_tag iterator_category; -private: - pointer Ptr, End; -public: - DenseMapIterator() : Ptr(nullptr), End(nullptr) {} - - DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch, - bool NoAdvance = false) - : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) { - assert(isHandleInSync() && "invalid construction!"); - if (!NoAdvance) AdvancePastEmptyBuckets(); - } - - // Converting ctor from non-const iterators to const iterators. SFINAE'd out - // for const iterator destinations so it doesn't end up as a user defined copy - // constructor. - template ::type> - DenseMapIterator( - const DenseMapIterator &I) - : DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {} - - reference operator*() const { - assert(isHandleInSync() && "invalid iterator access!"); - return *Ptr; - } - pointer operator->() const { - assert(isHandleInSync() && "invalid iterator access!"); - return Ptr; - } - - bool operator==(const ConstIterator &RHS) const { - assert((!Ptr || isHandleInSync()) && "handle not in sync!"); - assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!"); - assert(getEpochAddress() == RHS.getEpochAddress() && - "comparing incomparable iterators!"); - return Ptr == RHS.Ptr; - } - bool operator!=(const ConstIterator &RHS) const { - assert((!Ptr || isHandleInSync()) && "handle not in sync!"); - assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!"); - assert(getEpochAddress() == RHS.getEpochAddress() && - "comparing incomparable iterators!"); - return Ptr != RHS.Ptr; - } - - inline DenseMapIterator& operator++() { // Preincrement - assert(isHandleInSync() && "invalid iterator access!"); - ++Ptr; - AdvancePastEmptyBuckets(); - return *this; - } - DenseMapIterator operator++(int) { // Postincrement - assert(isHandleInSync() && "invalid iterator access!"); - DenseMapIterator tmp = *this; ++*this; return tmp; - } - -private: - void AdvancePastEmptyBuckets() { - const KeyT Empty = KeyInfoT::getEmptyKey(); - const KeyT Tombstone = KeyInfoT::getTombstoneKey(); - - while (Ptr != End && (KeyInfoT::isEqual(Ptr->getFirst(), Empty) || - KeyInfoT::isEqual(Ptr->getFirst(), Tombstone))) - ++Ptr; - } -}; - -template -static inline size_t -capacity_in_bytes(const DenseMap &X) { - return X.getMemorySize(); -} - -} // end namespace llvm - -#endif diff --git a/wpiutil/include/llvm/DenseMapInfo.h b/wpiutil/include/llvm/DenseMapInfo.h deleted file mode 100644 index 65e38cc..0000000 --- a/wpiutil/include/llvm/DenseMapInfo.h +++ /dev/null @@ -1,251 +0,0 @@ -//===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines DenseMapInfo traits for DenseMap. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_DENSEMAPINFO_H -#define LLVM_ADT_DENSEMAPINFO_H - -#include "llvm/ArrayRef.h" -#include "llvm/Hashing.h" -#include "llvm/StringRef.h" -#include "llvm/PointerLikeTypeTraits.h" -#include "llvm/type_traits.h" - -namespace llvm { - -template -struct DenseMapInfo { - //static inline T getEmptyKey(); - //static inline T getTombstoneKey(); - //static unsigned getHashValue(const T &Val); - //static bool isEqual(const T &LHS, const T &RHS); -}; - -template struct CachedHash { - CachedHash(T Val) : Val(std::move(Val)) { - Hash = DenseMapInfo::getHashValue(Val); - } - CachedHash(T Val, unsigned Hash) : Val(std::move(Val)), Hash(Hash) {} - T Val; - unsigned Hash; -}; - -// Provide DenseMapInfo for all CachedHash. -template struct DenseMapInfo> { - static CachedHash getEmptyKey() { - T N = DenseMapInfo::getEmptyKey(); - return {N, 0}; - } - static CachedHash getTombstoneKey() { - T N = DenseMapInfo::getTombstoneKey(); - return {N, 0}; - } - static unsigned getHashValue(CachedHash Val) { - assert(!isEqual(Val, getEmptyKey()) && "Cannot hash the empty key!"); - assert(!isEqual(Val, getTombstoneKey()) && - "Cannot hash the tombstone key!"); - return Val.Hash; - } - static bool isEqual(CachedHash A, CachedHash B) { - return DenseMapInfo::isEqual(A.Val, B.Val); - } -}; - -// Provide DenseMapInfo for all pointers. -template -struct DenseMapInfo { - static inline T* getEmptyKey() { - uintptr_t Val = static_cast(-1); - Val <<= PointerLikeTypeTraits::NumLowBitsAvailable; - return reinterpret_cast(Val); - } - static inline T* getTombstoneKey() { - uintptr_t Val = static_cast(-2); - Val <<= PointerLikeTypeTraits::NumLowBitsAvailable; - return reinterpret_cast(Val); - } - static unsigned getHashValue(const T *PtrVal) { - return (unsigned((uintptr_t)PtrVal) >> 4) ^ - (unsigned((uintptr_t)PtrVal) >> 9); - } - static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } -}; - -// Provide DenseMapInfo for chars. -template<> struct DenseMapInfo { - static inline char getEmptyKey() { return ~0; } - static inline char getTombstoneKey() { return ~0 - 1; } - static unsigned getHashValue(const char& Val) { return Val * 37U; } - static bool isEqual(const char &LHS, const char &RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for unsigned ints. -template<> struct DenseMapInfo { - static inline unsigned getEmptyKey() { return ~0U; } - static inline unsigned getTombstoneKey() { return ~0U - 1; } - static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } - static bool isEqual(const unsigned& LHS, const unsigned& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for unsigned longs. -template<> struct DenseMapInfo { - static inline unsigned long getEmptyKey() { return ~0UL; } - static inline unsigned long getTombstoneKey() { return ~0UL - 1L; } - static unsigned getHashValue(const unsigned long& Val) { - return (unsigned)(Val * 37UL); - } - static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for unsigned long longs. -template<> struct DenseMapInfo { - static inline unsigned long long getEmptyKey() { return ~0ULL; } - static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } - static unsigned getHashValue(const unsigned long long& Val) { - return (unsigned)(Val * 37ULL); - } - static bool isEqual(const unsigned long long& LHS, - const unsigned long long& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for ints. -template<> struct DenseMapInfo { - static inline int getEmptyKey() { return 0x7fffffff; } - static inline int getTombstoneKey() { return -0x7fffffff - 1; } - static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); } - static bool isEqual(const int& LHS, const int& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for longs. -template<> struct DenseMapInfo { - static inline long getEmptyKey() { - return (1UL << (sizeof(long) * 8 - 1)) - 1UL; - } - static inline long getTombstoneKey() { return getEmptyKey() - 1L; } - static unsigned getHashValue(const long& Val) { - return (unsigned)(Val * 37UL); - } - static bool isEqual(const long& LHS, const long& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for long longs. -template<> struct DenseMapInfo { - static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } - static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } - static unsigned getHashValue(const long long& Val) { - return (unsigned)(Val * 37ULL); - } - static bool isEqual(const long long& LHS, - const long long& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for all pairs whose members have info. -template -struct DenseMapInfo > { - typedef std::pair Pair; - typedef DenseMapInfo FirstInfo; - typedef DenseMapInfo SecondInfo; - - static inline Pair getEmptyKey() { - return std::make_pair(FirstInfo::getEmptyKey(), - SecondInfo::getEmptyKey()); - } - static inline Pair getTombstoneKey() { - return std::make_pair(FirstInfo::getTombstoneKey(), - SecondInfo::getTombstoneKey()); - } - static unsigned getHashValue(const Pair& PairVal) { - uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 - | (uint64_t)SecondInfo::getHashValue(PairVal.second); - key += ~(key << 32); - key ^= (key >> 22); - key += ~(key << 13); - key ^= (key >> 8); - key += (key << 3); - key ^= (key >> 15); - key += ~(key << 27); - key ^= (key >> 31); - return (unsigned)key; - } - static bool isEqual(const Pair &LHS, const Pair &RHS) { - return FirstInfo::isEqual(LHS.first, RHS.first) && - SecondInfo::isEqual(LHS.second, RHS.second); - } -}; - -// Provide DenseMapInfo for StringRefs. -template <> struct DenseMapInfo { - static inline StringRef getEmptyKey() { - return StringRef(reinterpret_cast(~static_cast(0)), - 0); - } - static inline StringRef getTombstoneKey() { - return StringRef(reinterpret_cast(~static_cast(1)), - 0); - } - static unsigned getHashValue(StringRef Val) { - assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!"); - assert(Val.data() != getTombstoneKey().data() && - "Cannot hash the tombstone key!"); - return (unsigned)(hash_value(Val)); - } - static bool isEqual(StringRef LHS, StringRef RHS) { - if (RHS.data() == getEmptyKey().data()) - return LHS.data() == getEmptyKey().data(); - if (RHS.data() == getTombstoneKey().data()) - return LHS.data() == getTombstoneKey().data(); - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for ArrayRefs. -template struct DenseMapInfo> { - static inline ArrayRef getEmptyKey() { - return ArrayRef(reinterpret_cast(~static_cast(0)), - size_t(0)); - } - static inline ArrayRef getTombstoneKey() { - return ArrayRef(reinterpret_cast(~static_cast(1)), - size_t(0)); - } - static unsigned getHashValue(ArrayRef Val) { - assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!"); - assert(Val.data() != getTombstoneKey().data() && - "Cannot hash the tombstone key!"); - return (unsigned)(hash_value(Val)); - } - static bool isEqual(ArrayRef LHS, ArrayRef RHS) { - if (RHS.data() == getEmptyKey().data()) - return LHS.data() == getEmptyKey().data(); - if (RHS.data() == getTombstoneKey().data()) - return LHS.data() == getTombstoneKey().data(); - return LHS == RHS; - } -}; - -} // end namespace llvm - -#endif diff --git a/wpiutil/include/llvm/EpochTracker.h b/wpiutil/include/llvm/EpochTracker.h deleted file mode 100644 index f589136..0000000 --- a/wpiutil/include/llvm/EpochTracker.h +++ /dev/null @@ -1,97 +0,0 @@ -//===- llvm/ADT/EpochTracker.h - ADT epoch tracking --------------*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the DebugEpochBase and DebugEpochBase::HandleBase classes. -// These can be used to write iterators that are fail-fast when LLVM is built -// with asserts enabled. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_EPOCH_TRACKER_H -#define LLVM_ADT_EPOCH_TRACKER_H - -#include - -namespace llvm { - -#ifdef NDEBUG //ifndef LLVM_ENABLE_ABI_BREAKING_CHECKS - -class DebugEpochBase { -public: - void incrementEpoch() {} - - class HandleBase { - public: - HandleBase() = default; - explicit HandleBase(const DebugEpochBase *) {} - bool isHandleInSync() const { return true; } - const void *getEpochAddress() const { return nullptr; } - }; -}; - -#else - -/// \brief A base class for data structure classes wishing to make iterators -/// ("handles") pointing into themselves fail-fast. When building without -/// asserts, this class is empty and does nothing. -/// -/// DebugEpochBase does not by itself track handles pointing into itself. The -/// expectation is that routines touching the handles will poll on -/// isHandleInSync at appropriate points to assert that the handle they're using -/// is still valid. -/// -class DebugEpochBase { - uint64_t Epoch; - -public: - DebugEpochBase() : Epoch(0) {} - - /// \brief Calling incrementEpoch invalidates all handles pointing into the - /// calling instance. - void incrementEpoch() { ++Epoch; } - - /// \brief The destructor calls incrementEpoch to make use-after-free bugs - /// more likely to crash deterministically. - ~DebugEpochBase() { incrementEpoch(); } - - /// \brief A base class for iterator classes ("handles") that wish to poll for - /// iterator invalidating modifications in the underlying data structure. - /// When LLVM is built without asserts, this class is empty and does nothing. - /// - /// HandleBase does not track the parent data structure by itself. It expects - /// the routines modifying the data structure to call incrementEpoch when they - /// make an iterator-invalidating modification. - /// - class HandleBase { - const uint64_t *EpochAddress; - uint64_t EpochAtCreation; - - public: - HandleBase() : EpochAddress(nullptr), EpochAtCreation(UINT64_MAX) {} - - explicit HandleBase(const DebugEpochBase *Parent) - : EpochAddress(&Parent->Epoch), EpochAtCreation(Parent->Epoch) {} - - /// \brief Returns true if the DebugEpochBase this Handle is linked to has - /// not called incrementEpoch on itself since the creation of this - /// HandleBase instance. - bool isHandleInSync() const { return *EpochAddress == EpochAtCreation; } - - /// \brief Returns a pointer to the epoch word stored in the data structure - /// this handle points into. Can be used to check if two iterators point - /// into the same data structure. - const void *getEpochAddress() const { return EpochAddress; } - }; -}; - -#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS - -} // namespace llvm - -#endif diff --git a/wpiutil/include/llvm/Format.h b/wpiutil/include/llvm/Format.h deleted file mode 100644 index 5138dec..0000000 --- a/wpiutil/include/llvm/Format.h +++ /dev/null @@ -1,202 +0,0 @@ -//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the format() function, which can be used with other -// LLVM subsystems to provide printf-style formatting. This gives all the power -// and risk of printf. This can be used like this (with raw_ostreams as an -// example): -// -// OS << "mynumber: " << format("%4.5f", 1234.412) << '\n'; -// -// Or if you prefer: -// -// OS << format("mynumber: %4.5f\n", 1234.412); -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_FORMAT_H -#define LLVM_SUPPORT_FORMAT_H - -#include "llvm/STLExtras.h" -#include "llvm/StringRef.h" -#include -#include -#include -#include - -namespace llvm { - -/// This is a helper class used for handling formatted output. It is the -/// abstract base class of a templated derived class. -class format_object_base { -protected: - const char *Fmt; - ~format_object_base() = default; // Disallow polymorphic deletion. - format_object_base(const format_object_base &) = default; - virtual void home(); // Out of line virtual method. - - /// Call snprintf() for this object, on the given buffer and size. - virtual int snprint(char *Buffer, unsigned BufferSize) const = 0; - -public: - format_object_base(const char *fmt) : Fmt(fmt) {} - - /// Format the object into the specified buffer. On success, this returns - /// the length of the formatted string. If the buffer is too small, this - /// returns a length to retry with, which will be larger than BufferSize. - unsigned print(char *Buffer, unsigned BufferSize) const { - assert(BufferSize && "Invalid buffer size!"); - - // Print the string, leaving room for the terminating null. - int N = snprint(Buffer, BufferSize); - - // VC++ and old GlibC return negative on overflow, just double the size. - if (N < 0) - return BufferSize * 2; - - // Other implementations yield number of bytes needed, not including the - // final '\0'. - if (unsigned(N) >= BufferSize) - return N + 1; - - // Otherwise N is the length of output (not including the final '\0'). - return N; - } -}; - -/// These are templated helper classes used by the format function that -/// capture the object to be formated and the format string. When actually -/// printed, this synthesizes the string into a temporary buffer provided and -/// returns whether or not it is big enough. - -template -class format_object final : public format_object_base { - std::tuple Vals; - - template - int snprint_tuple(char *Buffer, unsigned BufferSize, - index_sequence) const { -#ifdef _MSC_VER - return _snprintf(Buffer, BufferSize, Fmt, std::get(Vals)...); -#else -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" -#endif - return snprintf(Buffer, BufferSize, Fmt, std::get(Vals)...); -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif -#endif - } - -public: - format_object(const char *fmt, const Ts &... vals) - : format_object_base(fmt), Vals(vals...) {} - - int snprint(char *Buffer, unsigned BufferSize) const override { - return snprint_tuple(Buffer, BufferSize, index_sequence_for()); - } -}; - -/// These are helper functions used to produce formatted output. They use -/// template type deduction to construct the appropriate instance of the -/// format_object class to simplify their construction. -/// -/// This is typically used like: -/// \code -/// OS << format("%0.4f", myfloat) << '\n'; -/// \endcode - -template -inline format_object format(const char *Fmt, const Ts &... Vals) { - return format_object(Fmt, Vals...); -} - -/// This is a helper class used for left_justify() and right_justify(). -class FormattedString { - StringRef Str; - unsigned Width; - bool RightJustify; - friend class raw_ostream; - -public: - FormattedString(StringRef S, unsigned W, bool R) - : Str(S), Width(W), RightJustify(R) { } -}; - -/// left_justify - append spaces after string so total output is -/// \p Width characters. If \p Str is larger that \p Width, full string -/// is written with no padding. -inline FormattedString left_justify(StringRef Str, unsigned Width) { - return FormattedString(Str, Width, false); -} - -/// right_justify - add spaces before string so total output is -/// \p Width characters. If \p Str is larger that \p Width, full string -/// is written with no padding. -inline FormattedString right_justify(StringRef Str, unsigned Width) { - return FormattedString(Str, Width, true); -} - -/// This is a helper class used for format_hex() and format_decimal(). -class FormattedNumber { - uint64_t HexValue; - int64_t DecValue; - unsigned Width; - bool Hex; - bool Upper; - bool HexPrefix; - friend class raw_ostream; - -public: - FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U, - bool Prefix) - : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U), - HexPrefix(Prefix) {} -}; - -/// format_hex - Output \p N as a fixed width hexadecimal. If number will not -/// fit in width, full number is still printed. Examples: -/// OS << format_hex(255, 4) => 0xff -/// OS << format_hex(255, 4, true) => 0xFF -/// OS << format_hex(255, 6) => 0x00ff -/// OS << format_hex(255, 2) => 0xff -inline FormattedNumber format_hex(uint64_t N, unsigned Width, - bool Upper = false) { - assert(Width <= 18 && "hex width must be <= 18"); - return FormattedNumber(N, 0, Width, true, Upper, true); -} - -/// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not -/// prepend '0x' to the outputted string. If number will not fit in width, -/// full number is still printed. Examples: -/// OS << format_hex_no_prefix(255, 2) => ff -/// OS << format_hex_no_prefix(255, 2, true) => FF -/// OS << format_hex_no_prefix(255, 4) => 00ff -/// OS << format_hex_no_prefix(255, 1) => ff -inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, - bool Upper = false) { - assert(Width <= 16 && "hex width must be <= 16"); - return FormattedNumber(N, 0, Width, true, Upper, false); -} - -/// format_decimal - Output \p N as a right justified, fixed-width decimal. If -/// number will not fit in width, full number is still printed. Examples: -/// OS << format_decimal(0, 5) => " 0" -/// OS << format_decimal(255, 5) => " 255" -/// OS << format_decimal(-1, 3) => " -1" -/// OS << format_decimal(12345, 3) => "12345" -inline FormattedNumber format_decimal(int64_t N, unsigned Width) { - return FormattedNumber(0, N, Width, false, false, false); -} - -} // end namespace llvm - -#endif diff --git a/wpiutil/include/llvm/Hashing.h b/wpiutil/include/llvm/Hashing.h deleted file mode 100644 index 6efd99e..0000000 --- a/wpiutil/include/llvm/Hashing.h +++ /dev/null @@ -1,659 +0,0 @@ -//===-- llvm/ADT/Hashing.h - Utilities for hashing --------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the newly proposed standard C++ interfaces for hashing -// arbitrary data and building hash functions for user-defined types. This -// interface was originally proposed in N3333[1] and is currently under review -// for inclusion in a future TR and/or standard. -// -// The primary interfaces provide are comprised of one type and three functions: -// -// -- 'hash_code' class is an opaque type representing the hash code for some -// data. It is the intended product of hashing, and can be used to implement -// hash tables, checksumming, and other common uses of hashes. It is not an -// integer type (although it can be converted to one) because it is risky -// to assume much about the internals of a hash_code. In particular, each -// execution of the program has a high probability of producing a different -// hash_code for a given input. Thus their values are not stable to save or -// persist, and should only be used during the execution for the -// construction of hashing datastructures. -// -// -- 'hash_value' is a function designed to be overloaded for each -// user-defined type which wishes to be used within a hashing context. It -// should be overloaded within the user-defined type's namespace and found -// via ADL. Overloads for primitive types are provided by this library. -// -// -- 'hash_combine' and 'hash_combine_range' are functions designed to aid -// programmers in easily and intuitively combining a set of data into -// a single hash_code for their object. They should only logically be used -// within the implementation of a 'hash_value' routine or similar context. -// -// Note that 'hash_combine_range' contains very special logic for hashing -// a contiguous array of integers or pointers. This logic is *extremely* fast, -// on a modern Intel "Gainestown" Xeon (Nehalem uarch) @2.2 GHz, these were -// benchmarked at over 6.5 GiB/s for large keys, and <20 cycles/hash for keys -// under 32-bytes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_HASHING_H -#define LLVM_ADT_HASHING_H - -#include "llvm/type_traits.h" -#include -#include -#include -#include -#include -#include - -namespace llvm { - -/// \brief An opaque object representing a hash code. -/// -/// This object represents the result of hashing some entity. It is intended to -/// be used to implement hashtables or other hashing-based data structures. -/// While it wraps and exposes a numeric value, this value should not be -/// trusted to be stable or predictable across processes or executions. -/// -/// In order to obtain the hash_code for an object 'x': -/// \code -/// using llvm::hash_value; -/// llvm::hash_code code = hash_value(x); -/// \endcode -class hash_code { - size_t value; - -public: - /// \brief Default construct a hash_code. - /// Note that this leaves the value uninitialized. - hash_code() = default; - - /// \brief Form a hash code directly from a numerical value. - hash_code(size_t value) : value(value) {} - - /// \brief Convert the hash code to its numerical value for use. - /*explicit*/ operator size_t() const { return value; } - - friend bool operator==(const hash_code &lhs, const hash_code &rhs) { - return lhs.value == rhs.value; - } - friend bool operator!=(const hash_code &lhs, const hash_code &rhs) { - return lhs.value != rhs.value; - } - - /// \brief Allow a hash_code to be directly run through hash_value. - friend size_t hash_value(const hash_code &code) { return code.value; } -}; - -/// \brief Compute a hash_code for any integer value. -/// -/// Note that this function is intended to compute the same hash_code for -/// a particular value without regard to the pre-promotion type. This is in -/// contrast to hash_combine which may produce different hash_codes for -/// differing argument types even if they would implicit promote to a common -/// type without changing the value. -template -typename std::enable_if::value, hash_code>::type -hash_value(T value); - -/// \brief Compute a hash_code for a pointer's address. -/// -/// N.B.: This hashes the *address*. Not the value and not the type. -template hash_code hash_value(const T *ptr); - -/// \brief Compute a hash_code for a pair of objects. -template -hash_code hash_value(const std::pair &arg); - -/// \brief Compute a hash_code for a standard string. -template -hash_code hash_value(const std::basic_string &arg); - - -/// \brief Override the execution seed with a fixed value. -/// -/// This hashing library uses a per-execution seed designed to change on each -/// run with high probability in order to ensure that the hash codes are not -/// attackable and to ensure that output which is intended to be stable does -/// not rely on the particulars of the hash codes produced. -/// -/// That said, there are use cases where it is important to be able to -/// reproduce *exactly* a specific behavior. To that end, we provide a function -/// which will forcibly set the seed to a fixed value. This must be done at the -/// start of the program, before any hashes are computed. Also, it cannot be -/// undone. This makes it thread-hostile and very hard to use outside of -/// immediately on start of a simple program designed for reproducible -/// behavior. -void set_fixed_execution_hash_seed(size_t fixed_value); - - -// All of the implementation details of actually computing the various hash -// code values are held within this namespace. These routines are included in -// the header file mainly to allow inlining and constant propagation. -namespace hashing { -namespace detail { - -inline uint64_t fetch64(const char *p) { - uint64_t result; - memcpy(&result, p, sizeof(result)); - //if (sys::IsBigEndianHost) - // sys::swapByteOrder(result); - return result; -} - -inline uint32_t fetch32(const char *p) { - uint32_t result; - memcpy(&result, p, sizeof(result)); - //if (sys::IsBigEndianHost) - // sys::swapByteOrder(result); - return result; -} - -/// Some primes between 2^63 and 2^64 for various uses. -static const uint64_t k0 = 0xc3a5c85c97cb3127ULL; -static const uint64_t k1 = 0xb492b66fbe98f273ULL; -static const uint64_t k2 = 0x9ae16a3b2f90404fULL; -static const uint64_t k3 = 0xc949d7c7509e6557ULL; - -/// \brief Bitwise right rotate. -/// Normally this will compile to a single instruction, especially if the -/// shift is a manifest constant. -inline uint64_t rotate(uint64_t val, size_t shift) { - // Avoid shifting by 64: doing so yields an undefined result. - return shift == 0 ? val : ((val >> shift) | (val << (64 - shift))); -} - -inline uint64_t shift_mix(uint64_t val) { - return val ^ (val >> 47); -} - -inline uint64_t hash_16_bytes(uint64_t low, uint64_t high) { - // Murmur-inspired hashing. - const uint64_t kMul = 0x9ddfea08eb382d69ULL; - uint64_t a = (low ^ high) * kMul; - a ^= (a >> 47); - uint64_t b = (high ^ a) * kMul; - b ^= (b >> 47); - b *= kMul; - return b; -} - -inline uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed) { - uint8_t a = s[0]; - uint8_t b = s[len >> 1]; - uint8_t c = s[len - 1]; - uint32_t y = static_cast(a) + (static_cast(b) << 8); - uint32_t z = len + (static_cast(c) << 2); - return shift_mix(y * k2 ^ z * k3 ^ seed) * k2; -} - -inline uint64_t hash_4to8_bytes(const char *s, size_t len, uint64_t seed) { - uint64_t a = fetch32(s); - return hash_16_bytes(len + (a << 3), seed ^ fetch32(s + len - 4)); -} - -inline uint64_t hash_9to16_bytes(const char *s, size_t len, uint64_t seed) { - uint64_t a = fetch64(s); - uint64_t b = fetch64(s + len - 8); - return hash_16_bytes(seed ^ a, rotate(b + len, len)) ^ b; -} - -inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) { - uint64_t a = fetch64(s) * k1; - uint64_t b = fetch64(s + 8); - uint64_t c = fetch64(s + len - 8) * k2; - uint64_t d = fetch64(s + len - 16) * k0; - return hash_16_bytes(rotate(a - b, 43) + rotate(c ^ seed, 30) + d, - a + rotate(b ^ k3, 20) - c + len + seed); -} - -inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) { - uint64_t z = fetch64(s + 24); - uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0; - uint64_t b = rotate(a + z, 52); - uint64_t c = rotate(a, 37); - a += fetch64(s + 8); - c += rotate(a, 7); - a += fetch64(s + 16); - uint64_t vf = a + z; - uint64_t vs = b + rotate(a, 31) + c; - a = fetch64(s + 16) + fetch64(s + len - 32); - z = fetch64(s + len - 8); - b = rotate(a + z, 52); - c = rotate(a, 37); - a += fetch64(s + len - 24); - c += rotate(a, 7); - a += fetch64(s + len - 16); - uint64_t wf = a + z; - uint64_t ws = b + rotate(a, 31) + c; - uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0); - return shift_mix((seed ^ (r * k0)) + vs) * k2; -} - -inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) { - if (length >= 4 && length <= 8) - return hash_4to8_bytes(s, length, seed); - if (length > 8 && length <= 16) - return hash_9to16_bytes(s, length, seed); - if (length > 16 && length <= 32) - return hash_17to32_bytes(s, length, seed); - if (length > 32) - return hash_33to64_bytes(s, length, seed); - if (length != 0) - return hash_1to3_bytes(s, length, seed); - - return k2 ^ seed; -} - -/// \brief The intermediate state used during hashing. -/// Currently, the algorithm for computing hash codes is based on CityHash and -/// keeps 56 bytes of arbitrary state. -struct hash_state { - uint64_t h0, h1, h2, h3, h4, h5, h6; - - /// \brief Create a new hash_state structure and initialize it based on the - /// seed and the first 64-byte chunk. - /// This effectively performs the initial mix. - static hash_state create(const char *s, uint64_t seed) { - hash_state state = { - 0, seed, hash_16_bytes(seed, k1), rotate(seed ^ k1, 49), - seed * k1, shift_mix(seed), 0 }; - state.h6 = hash_16_bytes(state.h4, state.h5); - state.mix(s); - return state; - } - - /// \brief Mix 32-bytes from the input sequence into the 16-bytes of 'a' - /// and 'b', including whatever is already in 'a' and 'b'. - static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) { - a += fetch64(s); - uint64_t c = fetch64(s + 24); - b = rotate(b + a + c, 21); - uint64_t d = a; - a += fetch64(s + 8) + fetch64(s + 16); - b += rotate(a, 44) + d; - a += c; - } - - /// \brief Mix in a 64-byte buffer of data. - /// We mix all 64 bytes even when the chunk length is smaller, but we - /// record the actual length. - void mix(const char *s) { - h0 = rotate(h0 + h1 + h3 + fetch64(s + 8), 37) * k1; - h1 = rotate(h1 + h4 + fetch64(s + 48), 42) * k1; - h0 ^= h6; - h1 += h3 + fetch64(s + 40); - h2 = rotate(h2 + h5, 33) * k1; - h3 = h4 * k1; - h4 = h0 + h5; - mix_32_bytes(s, h3, h4); - h5 = h2 + h6; - h6 = h1 + fetch64(s + 16); - mix_32_bytes(s + 32, h5, h6); - std::swap(h2, h0); - } - - /// \brief Compute the final 64-bit hash code value based on the current - /// state and the length of bytes hashed. - uint64_t finalize(size_t length) { - return hash_16_bytes(hash_16_bytes(h3, h5) + shift_mix(h1) * k1 + h2, - hash_16_bytes(h4, h6) + shift_mix(length) * k1 + h0); - } -}; - - -/// \brief A global, fixed seed-override variable. -/// -/// This variable can be set using the \see llvm::set_fixed_execution_seed -/// function. See that function for details. Do not, under any circumstances, -/// set or read this variable. -extern size_t fixed_seed_override; - -inline size_t get_execution_seed() { - // FIXME: This needs to be a per-execution seed. This is just a placeholder - // implementation. Switching to a per-execution seed is likely to flush out - // instability bugs and so will happen as its own commit. - // - // However, if there is a fixed seed override set the first time this is - // called, return that instead of the per-execution seed. - const uint64_t seed_prime = 0xff51afd7ed558ccdULL; - static size_t seed = fixed_seed_override ? fixed_seed_override - : (size_t)seed_prime; - return seed; -} - - -/// \brief Trait to indicate whether a type's bits can be hashed directly. -/// -/// A type trait which is true if we want to combine values for hashing by -/// reading the underlying data. It is false if values of this type must -/// first be passed to hash_value, and the resulting hash_codes combined. -// -// FIXME: We want to replace is_integral_or_enum and is_pointer here with -// a predicate which asserts that comparing the underlying storage of two -// values of the type for equality is equivalent to comparing the two values -// for equality. For all the platforms we care about, this holds for integers -// and pointers, but there are platforms where it doesn't and we would like to -// support user-defined types which happen to satisfy this property. -template struct is_hashable_data - : std::integral_constant::value || - std::is_pointer::value) && - 64 % sizeof(T) == 0)> {}; - -// Special case std::pair to detect when both types are viable and when there -// is no alignment-derived padding in the pair. This is a bit of a lie because -// std::pair isn't truly POD, but it's close enough in all reasonable -// implementations for our use case of hashing the underlying data. -template struct is_hashable_data > - : std::integral_constant::value && - is_hashable_data::value && - (sizeof(T) + sizeof(U)) == - sizeof(std::pair))> {}; - -/// \brief Helper to get the hashable data representation for a type. -/// This variant is enabled when the type itself can be used. -template -typename std::enable_if::value, T>::type -get_hashable_data(const T &value) { - return value; -} -/// \brief Helper to get the hashable data representation for a type. -/// This variant is enabled when we must first call hash_value and use the -/// result as our data. -template -typename std::enable_if::value, size_t>::type -get_hashable_data(const T &value) { - using ::llvm::hash_value; - return hash_value(value); -} - -/// \brief Helper to store data from a value into a buffer and advance the -/// pointer into that buffer. -/// -/// This routine first checks whether there is enough space in the provided -/// buffer, and if not immediately returns false. If there is space, it -/// copies the underlying bytes of value into the buffer, advances the -/// buffer_ptr past the copied bytes, and returns true. -template -bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value, - size_t offset = 0) { - size_t store_size = sizeof(value) - offset; - if (buffer_ptr + store_size > buffer_end) - return false; - const char *value_data = reinterpret_cast(&value); - memcpy(buffer_ptr, value_data + offset, store_size); - buffer_ptr += store_size; - return true; -} - -/// \brief Implement the combining of integral values into a hash_code. -/// -/// This overload is selected when the value type of the iterator is -/// integral. Rather than computing a hash_code for each object and then -/// combining them, this (as an optimization) directly combines the integers. -template -hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) { - const size_t seed = get_execution_seed(); - char buffer[64], *buffer_ptr = buffer; - char *const buffer_end = std::end(buffer); - while (first != last && store_and_advance(buffer_ptr, buffer_end, - get_hashable_data(*first))) - ++first; - if (first == last) - return hash_short(buffer, buffer_ptr - buffer, seed); - assert(buffer_ptr == buffer_end); - - hash_state state = state.create(buffer, seed); - size_t length = 64; - while (first != last) { - // Fill up the buffer. We don't clear it, which re-mixes the last round - // when only a partial 64-byte chunk is left. - buffer_ptr = buffer; - while (first != last && store_and_advance(buffer_ptr, buffer_end, - get_hashable_data(*first))) - ++first; - - // Rotate the buffer if we did a partial fill in order to simulate doing - // a mix of the last 64-bytes. That is how the algorithm works when we - // have a contiguous byte sequence, and we want to emulate that here. - std::rotate(buffer, buffer_ptr, buffer_end); - - // Mix this chunk into the current state. - state.mix(buffer); - length += buffer_ptr - buffer; - }; - - return state.finalize(length); -} - -/// \brief Implement the combining of integral values into a hash_code. -/// -/// This overload is selected when the value type of the iterator is integral -/// and when the input iterator is actually a pointer. Rather than computing -/// a hash_code for each object and then combining them, this (as an -/// optimization) directly combines the integers. Also, because the integers -/// are stored in contiguous memory, this routine avoids copying each value -/// and directly reads from the underlying memory. -template -typename std::enable_if::value, hash_code>::type -hash_combine_range_impl(ValueT *first, ValueT *last) { - const size_t seed = get_execution_seed(); - const char *s_begin = reinterpret_cast(first); - const char *s_end = reinterpret_cast(last); - const size_t length = std::distance(s_begin, s_end); - if (length <= 64) - return hash_short(s_begin, length, seed); - - const char *s_aligned_end = s_begin + (length & ~63); - hash_state state = state.create(s_begin, seed); - s_begin += 64; - while (s_begin != s_aligned_end) { - state.mix(s_begin); - s_begin += 64; - } - if (length & 63) - state.mix(s_end - 64); - - return state.finalize(length); -} - -} // namespace detail -} // namespace hashing - - -/// \brief Compute a hash_code for a sequence of values. -/// -/// This hashes a sequence of values. It produces the same hash_code as -/// 'hash_combine(a, b, c, ...)', but can run over arbitrary sized sequences -/// and is significantly faster given pointers and types which can be hashed as -/// a sequence of bytes. -template -hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) { - return ::llvm::hashing::detail::hash_combine_range_impl(first, last); -} - - -// Implementation details for hash_combine. -namespace hashing { -namespace detail { - -/// \brief Helper class to manage the recursive combining of hash_combine -/// arguments. -/// -/// This class exists to manage the state and various calls involved in the -/// recursive combining of arguments used in hash_combine. It is particularly -/// useful at minimizing the code in the recursive calls to ease the pain -/// caused by a lack of variadic functions. -struct hash_combine_recursive_helper { - char buffer[64]; - hash_state state; - const size_t seed; - -public: - /// \brief Construct a recursive hash combining helper. - /// - /// This sets up the state for a recursive hash combine, including getting - /// the seed and buffer setup. - hash_combine_recursive_helper() - : seed(get_execution_seed()) {} - - /// \brief Combine one chunk of data into the current in-flight hash. - /// - /// This merges one chunk of data into the hash. First it tries to buffer - /// the data. If the buffer is full, it hashes the buffer into its - /// hash_state, empties it, and then merges the new chunk in. This also - /// handles cases where the data straddles the end of the buffer. - template - char *combine_data(size_t &length, char *buffer_ptr, char *buffer_end, T data) { - if (!store_and_advance(buffer_ptr, buffer_end, data)) { - // Check for skew which prevents the buffer from being packed, and do - // a partial store into the buffer to fill it. This is only a concern - // with the variadic combine because that formation can have varying - // argument types. - size_t partial_store_size = buffer_end - buffer_ptr; - memcpy(buffer_ptr, &data, partial_store_size); - - // If the store fails, our buffer is full and ready to hash. We have to - // either initialize the hash state (on the first full buffer) or mix - // this buffer into the existing hash state. Length tracks the *hashed* - // length, not the buffered length. - if (length == 0) { - state = state.create(buffer, seed); - length = 64; - } else { - // Mix this chunk into the current state and bump length up by 64. - state.mix(buffer); - length += 64; - } - // Reset the buffer_ptr to the head of the buffer for the next chunk of - // data. - buffer_ptr = buffer; - - // Try again to store into the buffer -- this cannot fail as we only - // store types smaller than the buffer. - if (!store_and_advance(buffer_ptr, buffer_end, data, - partial_store_size)) - abort(); - } - return buffer_ptr; - } - - /// \brief Recursive, variadic combining method. - /// - /// This function recurses through each argument, combining that argument - /// into a single hash. - template - hash_code combine(size_t length, char *buffer_ptr, char *buffer_end, - const T &arg, const Ts &...args) { - buffer_ptr = combine_data(length, buffer_ptr, buffer_end, get_hashable_data(arg)); - - // Recurse to the next argument. - return combine(length, buffer_ptr, buffer_end, args...); - } - - /// \brief Base case for recursive, variadic combining. - /// - /// The base case when combining arguments recursively is reached when all - /// arguments have been handled. It flushes the remaining buffer and - /// constructs a hash_code. - hash_code combine(size_t length, char *buffer_ptr, char *buffer_end) { - // Check whether the entire set of values fit in the buffer. If so, we'll - // use the optimized short hashing routine and skip state entirely. - if (length == 0) - return hash_short(buffer, buffer_ptr - buffer, seed); - - // Mix the final buffer, rotating it if we did a partial fill in order to - // simulate doing a mix of the last 64-bytes. That is how the algorithm - // works when we have a contiguous byte sequence, and we want to emulate - // that here. - std::rotate(buffer, buffer_ptr, buffer_end); - - // Mix this chunk into the current state. - state.mix(buffer); - length += buffer_ptr - buffer; - - return state.finalize(length); - } -}; - -} // namespace detail -} // namespace hashing - -/// \brief Combine values into a single hash_code. -/// -/// This routine accepts a varying number of arguments of any type. It will -/// attempt to combine them into a single hash_code. For user-defined types it -/// attempts to call a \see hash_value overload (via ADL) for the type. For -/// integer and pointer types it directly combines their data into the -/// resulting hash_code. -/// -/// The result is suitable for returning from a user's hash_value -/// *implementation* for their user-defined type. Consumers of a type should -/// *not* call this routine, they should instead call 'hash_value'. -template hash_code hash_combine(const Ts &...args) { - // Recursively hash each argument using a helper class. - ::llvm::hashing::detail::hash_combine_recursive_helper helper; - return helper.combine(0, helper.buffer, helper.buffer + 64, args...); -} - -// Implementation details for implementations of hash_value overloads provided -// here. -namespace hashing { -namespace detail { - -/// \brief Helper to hash the value of a single integer. -/// -/// Overloads for smaller integer types are not provided to ensure consistent -/// behavior in the presence of integral promotions. Essentially, -/// "hash_value('4')" and "hash_value('0' + 4)" should be the same. -inline hash_code hash_integer_value(uint64_t value) { - // Similar to hash_4to8_bytes but using a seed instead of length. - const uint64_t seed = get_execution_seed(); - const char *s = reinterpret_cast(&value); - const uint64_t a = fetch32(s); - return hash_16_bytes(seed + (a << 3), fetch32(s + 4)); -} - -} // namespace detail -} // namespace hashing - -// Declared and documented above, but defined here so that any of the hashing -// infrastructure is available. -template -typename std::enable_if::value, hash_code>::type -hash_value(T value) { - return ::llvm::hashing::detail::hash_integer_value( - static_cast(value)); -} - -// Declared and documented above, but defined here so that any of the hashing -// infrastructure is available. -template hash_code hash_value(const T *ptr) { - return ::llvm::hashing::detail::hash_integer_value( - reinterpret_cast(ptr)); -} - -// Declared and documented above, but defined here so that any of the hashing -// infrastructure is available. -template -hash_code hash_value(const std::pair &arg) { - return hash_combine(arg.first, arg.second); -} - -// Declared and documented above, but defined here so that any of the hashing -// infrastructure is available. -template -hash_code hash_value(const std::basic_string &arg) { - return hash_combine_range(arg.begin(), arg.end()); -} - -} // namespace llvm - -#endif diff --git a/wpiutil/include/llvm/MathExtras.h b/wpiutil/include/llvm/MathExtras.h deleted file mode 100644 index a8258ba..0000000 --- a/wpiutil/include/llvm/MathExtras.h +++ /dev/null @@ -1,653 +0,0 @@ -//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains some functions that are useful for math stuff. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_MATHEXTRAS_H -#define LLVM_SUPPORT_MATHEXTRAS_H - -#include "llvm/Compiler.h" -#include -#include -#include -#include -#include -#include -#include - -#ifdef _MSC_VER -#include -#endif - -namespace llvm { -/// \brief The behavior an operation has on an input of 0. -enum ZeroBehavior { - /// \brief The returned value is undefined. - ZB_Undefined, - /// \brief The returned value is numeric_limits::max() - ZB_Max, - /// \brief The returned value is numeric_limits::digits - ZB_Width -}; - -namespace detail { -template struct LeadingZerosCounter { - static std::size_t count(T Val, ZeroBehavior) { - if (!Val) - return std::numeric_limits::digits; - - // Bisection method. - std::size_t ZeroBits = 0; - for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { - T Tmp = Val >> Shift; - if (Tmp) - Val = Tmp; - else - ZeroBits |= Shift; - } - return ZeroBits; - } -}; - -#if __GNUC__ >= 4 || defined(_MSC_VER) -template struct LeadingZerosCounter { - static std::size_t count(T Val, ZeroBehavior ZB) { - if (ZB != ZB_Undefined && Val == 0) - return 32; - -#if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0) - return __builtin_clz(Val); -#elif defined(_MSC_VER) - unsigned long Index; - _BitScanReverse(&Index, Val); - return Index ^ 31; -#endif - } -}; - -#if !defined(_MSC_VER) || defined(_M_X64) -template struct LeadingZerosCounter { - static std::size_t count(T Val, ZeroBehavior ZB) { - if (ZB != ZB_Undefined && Val == 0) - return 64; - -#if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0) - return __builtin_clzll(Val); -#elif defined(_MSC_VER) - unsigned long Index; - _BitScanReverse64(&Index, Val); - return Index ^ 63; -#endif - } -}; -#endif -#endif -} // namespace detail - -/// \brief Count number of 0's from the most significant bit to the least -/// stopping at the first 1. -/// -/// Only unsigned integral types are allowed. -/// -/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are -/// valid arguments. -template -std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, - "Only unsigned integral types are allowed."); - return detail::LeadingZerosCounter::count(Val, ZB); -} - -/// \brief Get the index of the last set bit starting from the least -/// significant bit. -/// -/// Only unsigned integral types are allowed. -/// -/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are -/// valid arguments. -template T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { - if (ZB == ZB_Max && Val == 0) - return std::numeric_limits::max(); - - // Use ^ instead of - because both gcc and llvm can remove the associated ^ - // in the __builtin_clz intrinsic on x86. - return countLeadingZeros(Val, ZB_Undefined) ^ - (std::numeric_limits::digits - 1); -} - -/// \brief Macro compressed bit reversal table for 256 bits. -/// -/// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable -static const unsigned char BitReverseTable256[256] = { -#define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64 -#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16) -#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4) - R6(0), R6(2), R6(1), R6(3) -#undef R2 -#undef R4 -#undef R6 -}; - -/// \brief Reverse the bits in \p Val. -template -T reverseBits(T Val) { - unsigned char in[sizeof(Val)]; - unsigned char out[sizeof(Val)]; - std::memcpy(in, &Val, sizeof(Val)); - for (unsigned i = 0; i < sizeof(Val); ++i) - out[(sizeof(Val) - i) - 1] = BitReverseTable256[in[i]]; - std::memcpy(&Val, out, sizeof(Val)); - return Val; -} - -// NOTE: The following support functions use the _32/_64 extensions instead of -// type overloading so that signed and unsigned integers can be used without -// ambiguity. - -/// Hi_32 - This function returns the high 32 bits of a 64 bit value. -inline uint32_t Hi_32(uint64_t Value) { - return static_cast(Value >> 32); -} - -/// Lo_32 - This function returns the low 32 bits of a 64 bit value. -inline uint32_t Lo_32(uint64_t Value) { - return static_cast(Value); -} - -/// Make_64 - This functions makes a 64-bit integer from a high / low pair of -/// 32-bit integers. -inline uint64_t Make_64(uint32_t High, uint32_t Low) { - return ((uint64_t)High << 32) | (uint64_t)Low; -} - -/// isInt - Checks if an integer fits into the given bit width. -template -inline bool isInt(int64_t x) { - return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1))); -} -// Template specializations to get better code for common cases. -template<> -inline bool isInt<8>(int64_t x) { - return static_cast(x) == x; -} -template<> -inline bool isInt<16>(int64_t x) { - return static_cast(x) == x; -} -template<> -inline bool isInt<32>(int64_t x) { - return static_cast(x) == x; -} - -/// isShiftedInt - Checks if a signed integer is an N bit number shifted -/// left by S. -template -inline bool isShiftedInt(int64_t x) { - return isInt(x) && (x % (1< -inline bool isUInt(uint64_t x) { - return N >= 64 || x < (UINT64_C(1)<<(N)); -} -// Template specializations to get better code for common cases. -template<> -inline bool isUInt<8>(uint64_t x) { - return static_cast(x) == x; -} -template<> -inline bool isUInt<16>(uint64_t x) { - return static_cast(x) == x; -} -template<> -inline bool isUInt<32>(uint64_t x) { - return static_cast(x) == x; -} - -/// isShiftedUInt - Checks if a unsigned integer is an N bit number shifted -/// left by S. -template -inline bool isShiftedUInt(uint64_t x) { - return isUInt(x) && (x % (1< 0 && N <= 64 && "integer width out of range"); - - return (UINT64_C(1) << N) - 1; -} - -/// Gets the minimum value for a N-bit signed integer. -inline int64_t minIntN(int64_t N) { - assert(N > 0 && N <= 64 && "integer width out of range"); - - return -(INT64_C(1)<<(N-1)); -} - -/// Gets the maximum value for a N-bit signed integer. -inline int64_t maxIntN(int64_t N) { - assert(N > 0 && N <= 64 && "integer width out of range"); - - return (INT64_C(1)<<(N-1)) - 1; -} - -/// isUIntN - Checks if an unsigned integer fits into the given (dynamic) -/// bit width. -inline bool isUIntN(unsigned N, uint64_t x) { - return N >= 64 || x <= maxUIntN(N); -} - -/// isIntN - Checks if an signed integer fits into the given (dynamic) -/// bit width. -inline bool isIntN(unsigned N, int64_t x) { - return N >= 64 || (minIntN(N) <= x && x <= maxIntN(N)); -} - -/// isMask_32 - This function returns true if the argument is a non-empty -/// sequence of ones starting at the least significant bit with the remainder -/// zero (32 bit version). Ex. isMask_32(0x0000FFFFU) == true. -inline bool isMask_32(uint32_t Value) { - return Value && ((Value + 1) & Value) == 0; -} - -/// isMask_64 - This function returns true if the argument is a non-empty -/// sequence of ones starting at the least significant bit with the remainder -/// zero (64 bit version). -inline bool isMask_64(uint64_t Value) { - return Value && ((Value + 1) & Value) == 0; -} - -/// isShiftedMask_32 - This function returns true if the argument contains a -/// non-empty sequence of ones with the remainder zero (32 bit version.) -/// Ex. isShiftedMask_32(0x0000FF00U) == true. -inline bool isShiftedMask_32(uint32_t Value) { - return Value && isMask_32((Value - 1) | Value); -} - -/// isShiftedMask_64 - This function returns true if the argument contains a -/// non-empty sequence of ones with the remainder zero (64 bit version.) -inline bool isShiftedMask_64(uint64_t Value) { - return Value && isMask_64((Value - 1) | Value); -} - -/// isPowerOf2_32 - This function returns true if the argument is a power of -/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.) -inline bool isPowerOf2_32(uint32_t Value) { - return Value && !(Value & (Value - 1)); -} - -/// isPowerOf2_64 - This function returns true if the argument is a power of two -/// > 0 (64 bit edition.) -inline bool isPowerOf2_64(uint64_t Value) { - return Value && !(Value & (Value - int64_t(1L))); -} - -/// \brief Count the number of ones from the most significant bit to the first -/// zero bit. -/// -/// Ex. CountLeadingOnes(0xFF0FFF00) == 8. -/// Only unsigned integral types are allowed. -/// -/// \param ZB the behavior on an input of all ones. Only ZB_Width and -/// ZB_Undefined are valid arguments. -template -std::size_t countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, - "Only unsigned integral types are allowed."); - return countLeadingZeros(~Value, ZB); -} - -namespace detail { -template struct PopulationCounter { - static unsigned count(T Value) { - // Generic version, forward to 32 bits. - static_assert(SizeOfT <= 4, "Not implemented!"); -#if __GNUC__ >= 4 - return __builtin_popcount(Value); -#else - uint32_t v = Value; - v = v - ((v >> 1) & 0x55555555); - v = (v & 0x33333333) + ((v >> 2) & 0x33333333); - return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; -#endif - } -}; - -template struct PopulationCounter { - static unsigned count(T Value) { -#if __GNUC__ >= 4 - return __builtin_popcountll(Value); -#else - uint64_t v = Value; - v = v - ((v >> 1) & 0x5555555555555555ULL); - v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL); - v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL; - return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56); -#endif - } -}; -} // namespace detail - -/// \brief Count the number of set bits in a value. -/// Ex. countPopulation(0xF000F000) = 8 -/// Returns 0 if the word is zero. -template -inline unsigned countPopulation(T Value) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, - "Only unsigned integral types are allowed."); - return detail::PopulationCounter::count(Value); -} - -/// Log2 - This function returns the log base 2 of the specified value -inline double Log2(double Value) { -#if defined(__ANDROID_API__) && __ANDROID_API__ < 18 - return __builtin_log(Value) / __builtin_log(2.0); -#else - return std::log2(Value); -#endif -} - -/// Log2_32 - This function returns the floor log base 2 of the specified value, -/// -1 if the value is zero. (32 bit edition.) -/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 -inline unsigned Log2_32(uint32_t Value) { - return 31 - countLeadingZeros(Value); -} - -/// Log2_64 - This function returns the floor log base 2 of the specified value, -/// -1 if the value is zero. (64 bit edition.) -inline unsigned Log2_64(uint64_t Value) { - return 63 - countLeadingZeros(Value); -} - -/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified -/// value, 32 if the value is zero. (32 bit edition). -/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 -inline unsigned Log2_32_Ceil(uint32_t Value) { - return 32 - countLeadingZeros(Value - 1); -} - -/// Log2_64_Ceil - This function returns the ceil log base 2 of the specified -/// value, 64 if the value is zero. (64 bit edition.) -inline unsigned Log2_64_Ceil(uint64_t Value) { - return 64 - countLeadingZeros(Value - 1); -} - -/// GreatestCommonDivisor64 - Return the greatest common divisor of the two -/// values using Euclid's algorithm. -inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) { - while (B) { - uint64_t T = B; - B = A % B; - A = T; - } - return A; -} - -/// BitsToDouble - This function takes a 64-bit integer and returns the bit -/// equivalent double. -inline double BitsToDouble(uint64_t Bits) { - union { - uint64_t L; - double D; - } T; - T.L = Bits; - return T.D; -} - -/// BitsToFloat - This function takes a 32-bit integer and returns the bit -/// equivalent float. -inline float BitsToFloat(uint32_t Bits) { - union { - uint32_t I; - float F; - } T; - T.I = Bits; - return T.F; -} - -/// DoubleToBits - This function takes a double and returns the bit -/// equivalent 64-bit integer. Note that copying doubles around -/// changes the bits of NaNs on some hosts, notably x86, so this -/// routine cannot be used if these bits are needed. -inline uint64_t DoubleToBits(double Double) { - union { - uint64_t L; - double D; - } T; - T.D = Double; - return T.L; -} - -/// FloatToBits - This function takes a float and returns the bit -/// equivalent 32-bit integer. Note that copying floats around -/// changes the bits of NaNs on some hosts, notably x86, so this -/// routine cannot be used if these bits are needed. -inline uint32_t FloatToBits(float Float) { - union { - uint32_t I; - float F; - } T; - T.F = Float; - return T.I; -} - -/// MinAlign - A and B are either alignments or offsets. Return the minimum -/// alignment that may be assumed after adding the two together. -inline uint64_t MinAlign(uint64_t A, uint64_t B) { - // The largest power of 2 that divides both A and B. - // - // Replace "-Value" by "1+~Value" in the following commented code to avoid - // MSVC warning C4146 - // return (A | B) & -(A | B); - return (A | B) & (1 + ~(A | B)); -} - -/// \brief Aligns \c Addr to \c Alignment bytes, rounding up. -/// -/// Alignment should be a power of two. This method rounds up, so -/// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8. -inline uintptr_t alignAddr(const void *Addr, size_t Alignment) { - assert(Alignment && isPowerOf2_64((uint64_t)Alignment) && - "Alignment is not a power of two!"); - - assert((uintptr_t)Addr + Alignment - 1 >= (uintptr_t)Addr); - - return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1)); -} - -/// \brief Returns the necessary adjustment for aligning \c Ptr to \c Alignment -/// bytes, rounding up. -inline size_t alignmentAdjustment(const void *Ptr, size_t Alignment) { - return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr; -} - -/// NextPowerOf2 - Returns the next power of two (in 64-bits) -/// that is strictly greater than A. Returns zero on overflow. -inline uint64_t NextPowerOf2(uint64_t A) { - A |= (A >> 1); - A |= (A >> 2); - A |= (A >> 4); - A |= (A >> 8); - A |= (A >> 16); - A |= (A >> 32); - return A + 1; -} - -/// Returns the power of two which is less than or equal to the given value. -/// Essentially, it is a floor operation across the domain of powers of two. -inline uint64_t PowerOf2Floor(uint64_t A) { - if (!A) return 0; - return 1ull << (63 - countLeadingZeros(A, ZB_Undefined)); -} - -/// Returns the next integer (mod 2**64) that is greater than or equal to -/// \p Value and is a multiple of \p Align. \p Align must be non-zero. -/// -/// If non-zero \p Skew is specified, the return value will be a minimal -/// integer that is greater than or equal to \p Value and equal to -/// \p Align * N + \p Skew for some integer N. If \p Skew is larger than -/// \p Align, its value is adjusted to '\p Skew mod \p Align'. -/// -/// Examples: -/// \code -/// alignTo(5, 8) = 8 -/// alignTo(17, 8) = 24 -/// alignTo(~0LL, 8) = 0 -/// alignTo(321, 255) = 510 -/// -/// alignTo(5, 8, 7) = 7 -/// alignTo(17, 8, 1) = 17 -/// alignTo(~0LL, 8, 3) = 3 -/// alignTo(321, 255, 42) = 552 -/// \endcode -inline uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew = 0) { - Skew %= Align; - return (Value + Align - 1 - Skew) / Align * Align + Skew; -} - -/// Returns the largest uint64_t less than or equal to \p Value and is -/// \p Skew mod \p Align. \p Align must be non-zero -inline uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew = 0) { - Skew %= Align; - return (Value - Skew) / Align * Align + Skew; -} - -/// Returns the offset to the next integer (mod 2**64) that is greater than -/// or equal to \p Value and is a multiple of \p Align. \p Align must be -/// non-zero. -inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) { - return alignTo(Value, Align) - Value; -} - -/// SignExtend32 - Sign extend B-bit number x to 32-bit int. -/// Usage int32_t r = SignExtend32<5>(x); -template inline int32_t SignExtend32(uint32_t x) { - return int32_t(x << (32 - B)) >> (32 - B); -} - -/// \brief Sign extend number in the bottom B bits of X to a 32-bit int. -/// Requires 0 < B <= 32. -inline int32_t SignExtend32(uint32_t X, unsigned B) { - return int32_t(X << (32 - B)) >> (32 - B); -} - -/// SignExtend64 - Sign extend B-bit number x to 64-bit int. -/// Usage int64_t r = SignExtend64<5>(x); -template inline int64_t SignExtend64(uint64_t x) { - return int64_t(x << (64 - B)) >> (64 - B); -} - -/// \brief Sign extend number in the bottom B bits of X to a 64-bit int. -/// Requires 0 < B <= 64. -inline int64_t SignExtend64(uint64_t X, unsigned B) { - return int64_t(X << (64 - B)) >> (64 - B); -} - -/// \brief Subtract two unsigned integers, X and Y, of type T and return their -/// absolute value. -template -typename std::enable_if::value, T>::type -AbsoluteDifference(T X, T Y) { - return std::max(X, Y) - std::min(X, Y); -} - -/// \brief Add two unsigned integers, X and Y, of type T. -/// Clamp the result to the maximum representable value of T on overflow. -/// ResultOverflowed indicates if the result is larger than the maximum -/// representable value of type T. -template -typename std::enable_if::value, T>::type -SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) { - bool Dummy; - bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; - // Hacker's Delight, p. 29 - T Z = X + Y; - Overflowed = (Z < X || Z < Y); - if (Overflowed) - return std::numeric_limits::max(); - else - return Z; -} - -/// \brief Multiply two unsigned integers, X and Y, of type T. -/// Clamp the result to the maximum representable value of T on overflow. -/// ResultOverflowed indicates if the result is larger than the maximum -/// representable value of type T. -template -typename std::enable_if::value, T>::type -SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) { - bool Dummy; - bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; - - // Hacker's Delight, p. 30 has a different algorithm, but we don't use that - // because it fails for uint16_t (where multiplication can have undefined - // behavior due to promotion to int), and requires a division in addition - // to the multiplication. - - Overflowed = false; - - // Log2(Z) would be either Log2Z or Log2Z + 1. - // Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z - // will necessarily be less than Log2Max as desired. - int Log2Z = Log2_64(X) + Log2_64(Y); - const T Max = std::numeric_limits::max(); - int Log2Max = Log2_64(Max); - if (Log2Z < Log2Max) { - return X * Y; - } - if (Log2Z > Log2Max) { - Overflowed = true; - return Max; - } - - // We're going to use the top bit, and maybe overflow one - // bit past it. Multiply all but the bottom bit then add - // that on at the end. - T Z = (X >> 1) * Y; - if (Z & ~(Max >> 1)) { - Overflowed = true; - return Max; - } - Z <<= 1; - if (X & 1) - return SaturatingAdd(Z, Y, ResultOverflowed); - - return Z; -} - -/// \brief Multiply two unsigned integers, X and Y, and add the unsigned -/// integer, A to the product. Clamp the result to the maximum representable -/// value of T on overflow. ResultOverflowed indicates if the result is larger -/// than the maximum representable value of type T. -/// Note that this is purely a convenience function as there is no distinction -/// where overflow occurred in a 'fused' multiply-add for unsigned numbers. -template -typename std::enable_if::value, T>::type -SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) { - bool Dummy; - bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; - - T Product = SaturatingMultiply(X, Y, &Overflowed); - if (Overflowed) - return Product; - - return SaturatingAdd(A, Product, &Overflowed); -} - -} // namespace llvm - -#endif diff --git a/wpiutil/include/llvm/None.h b/wpiutil/include/llvm/None.h deleted file mode 100644 index d69ec17..0000000 --- a/wpiutil/include/llvm/None.h +++ /dev/null @@ -1,26 +0,0 @@ -//===-- None.h - Simple null value for implicit construction ------*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides None, an enumerator for use in implicit constructors -// of various (usually templated) types to make such construction more -// terse. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_NONE_H -#define LLVM_ADT_NONE_H - -namespace llvm { -/// \brief A simple null object to allow implicit construction of Optional -/// and similar types without having to spell out the specialization's name. -enum class NoneType { None }; -const NoneType None = None; -} - -#endif diff --git a/wpiutil/include/llvm/Optional.h b/wpiutil/include/llvm/Optional.h deleted file mode 100644 index a494c56..0000000 --- a/wpiutil/include/llvm/Optional.h +++ /dev/null @@ -1,228 +0,0 @@ -//===-- Optional.h - Simple variant for passing optional values ---*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides Optional, a template class modeled in the spirit of -// OCaml's 'opt' variant. The idea is to strongly type whether or not -// a value can be optional. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_OPTIONAL_H -#define LLVM_ADT_OPTIONAL_H - -#include "llvm/None.h" -#include "llvm/AlignOf.h" -#include "llvm/Compiler.h" -#include -#include -#include - -namespace llvm { - -template -class Optional { - AlignedCharArrayUnion storage; - bool hasVal; -public: - typedef T value_type; - - Optional(NoneType) : hasVal(false) {} - explicit Optional() : hasVal(false) {} - Optional(const T &y) : hasVal(true) { - new (storage.buffer) T(y); - } - Optional(const Optional &O) : hasVal(O.hasVal) { - if (hasVal) - new (storage.buffer) T(*O); - } - - Optional(T &&y) : hasVal(true) { - new (storage.buffer) T(std::forward(y)); - } - Optional(Optional &&O) : hasVal(O) { - if (O) { - new (storage.buffer) T(std::move(*O)); - O.reset(); - } - } - Optional &operator=(T &&y) { - if (hasVal) - **this = std::move(y); - else { - new (storage.buffer) T(std::move(y)); - hasVal = true; - } - return *this; - } - Optional &operator=(Optional &&O) { - if (!O) - reset(); - else { - *this = std::move(*O); - O.reset(); - } - return *this; - } - - /// Create a new object by constructing it in place with the given arguments. - template - void emplace(ArgTypes &&...Args) { - reset(); - hasVal = true; - new (storage.buffer) T(std::forward(Args)...); - } - - static inline Optional create(const T* y) { - return y ? Optional(*y) : Optional(); - } - - // FIXME: these assignments (& the equivalent const T&/const Optional& ctors) - // could be made more efficient by passing by value, possibly unifying them - // with the rvalue versions above - but this could place a different set of - // requirements (notably: the existence of a default ctor) when implemented - // in that way. Careful SFINAE to avoid such pitfalls would be required. - Optional &operator=(const T &y) { - if (hasVal) - **this = y; - else { - new (storage.buffer) T(y); - hasVal = true; - } - return *this; - } - - Optional &operator=(const Optional &O) { - if (!O) - reset(); - else - *this = *O; - return *this; - } - - void reset() { - if (hasVal) { - (**this).~T(); - hasVal = false; - } - } - - ~Optional() { - reset(); - } - - const T* getPointer() const { assert(hasVal); return reinterpret_cast(storage.buffer); } - T* getPointer() { assert(hasVal); return reinterpret_cast(storage.buffer); } - const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } - T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } - - explicit operator bool() const { return hasVal; } - bool hasValue() const { return hasVal; } - const T* operator->() const { return getPointer(); } - T* operator->() { return getPointer(); } - const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } - T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } - - template - LLVM_CONSTEXPR T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION { - return hasValue() ? getValue() : std::forward(value); - } - -#if LLVM_HAS_RVALUE_REFERENCE_THIS - T&& getValue() && { assert(hasVal); return std::move(*getPointer()); } - T&& operator*() && { assert(hasVal); return std::move(*getPointer()); } - - template - T getValueOr(U &&value) && { - return hasValue() ? std::move(getValue()) : std::forward(value); - } -#endif -}; - -template struct isPodLike; -template struct isPodLike > { - // An Optional is pod-like if T is. - static const bool value = isPodLike::value; -}; - -/// \brief Poison comparison between two \c Optional objects. Clients needs to -/// explicitly compare the underlying values and account for empty \c Optional -/// objects. -/// -/// This routine will never be defined. It returns \c void to help diagnose -/// errors at compile time. -template -void operator==(const Optional &X, const Optional &Y); - -template -bool operator==(const Optional &X, NoneType) { - return !X.hasValue(); -} - -template -bool operator==(NoneType, const Optional &X) { - return X == None; -} - -template -bool operator!=(const Optional &X, NoneType) { - return !(X == None); -} - -template -bool operator!=(NoneType, const Optional &X) { - return X != None; -} -/// \brief Poison comparison between two \c Optional objects. Clients needs to -/// explicitly compare the underlying values and account for empty \c Optional -/// objects. -/// -/// This routine will never be defined. It returns \c void to help diagnose -/// errors at compile time. -template -void operator!=(const Optional &X, const Optional &Y); - -/// \brief Poison comparison between two \c Optional objects. Clients needs to -/// explicitly compare the underlying values and account for empty \c Optional -/// objects. -/// -/// This routine will never be defined. It returns \c void to help diagnose -/// errors at compile time. -template -void operator<(const Optional &X, const Optional &Y); - -/// \brief Poison comparison between two \c Optional objects. Clients needs to -/// explicitly compare the underlying values and account for empty \c Optional -/// objects. -/// -/// This routine will never be defined. It returns \c void to help diagnose -/// errors at compile time. -template -void operator<=(const Optional &X, const Optional &Y); - -/// \brief Poison comparison between two \c Optional objects. Clients needs to -/// explicitly compare the underlying values and account for empty \c Optional -/// objects. -/// -/// This routine will never be defined. It returns \c void to help diagnose -/// errors at compile time. -template -void operator>=(const Optional &X, const Optional &Y); - -/// \brief Poison comparison between two \c Optional objects. Clients needs to -/// explicitly compare the underlying values and account for empty \c Optional -/// objects. -/// -/// This routine will never be defined. It returns \c void to help diagnose -/// errors at compile time. -template -void operator>(const Optional &X, const Optional &Y); - -} // end llvm namespace - -#endif diff --git a/wpiutil/include/llvm/PointerLikeTypeTraits.h b/wpiutil/include/llvm/PointerLikeTypeTraits.h deleted file mode 100644 index 3b96694..0000000 --- a/wpiutil/include/llvm/PointerLikeTypeTraits.h +++ /dev/null @@ -1,94 +0,0 @@ -//===- llvm/Support/PointerLikeTypeTraits.h - Pointer Traits ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PointerLikeTypeTraits class. This allows data -// structures to reason about pointers and other things that are pointer sized. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H -#define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H - -#include "llvm/AlignOf.h" -#include - -namespace llvm { - -/// A traits type that is used to handle pointer types and things that are just -/// wrappers for pointers as a uniform entity. -template class PointerLikeTypeTraits { - // getAsVoidPointer - // getFromVoidPointer - // getNumLowBitsAvailable -}; - -namespace detail { -/// A tiny meta function to compute the log2 of a compile time constant. -template -struct ConstantLog2 - : std::integral_constant::value + 1> {}; -template <> struct ConstantLog2<1> : std::integral_constant {}; -} - -// Provide PointerLikeTypeTraits for non-cvr pointers. -template class PointerLikeTypeTraits { -public: - static inline void *getAsVoidPointer(T *P) { return P; } - static inline T *getFromVoidPointer(void *P) { return static_cast(P); } - - enum { - NumLowBitsAvailable = detail::ConstantLog2::Alignment>::value - }; -}; - -template <> class PointerLikeTypeTraits { -public: - static inline void *getAsVoidPointer(void *P) { return P; } - static inline void *getFromVoidPointer(void *P) { return P; } - - /// Note, we assume here that void* is related to raw malloc'ed memory and - /// that malloc returns objects at least 4-byte aligned. However, this may be - /// wrong, or pointers may be from something other than malloc. In this case, - /// you should specify a real typed pointer or avoid this template. - /// - /// All clients should use assertions to do a run-time check to ensure that - /// this is actually true. - enum { NumLowBitsAvailable = 2 }; -}; - -// Provide PointerLikeTypeTraits for const pointers. -template class PointerLikeTypeTraits { - typedef PointerLikeTypeTraits NonConst; - -public: - static inline const void *getAsVoidPointer(const T *P) { - return NonConst::getAsVoidPointer(const_cast(P)); - } - static inline const T *getFromVoidPointer(const void *P) { - return NonConst::getFromVoidPointer(const_cast(P)); - } - enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable }; -}; - -// Provide PointerLikeTypeTraits for uintptr_t. -template <> class PointerLikeTypeTraits { -public: - static inline void *getAsVoidPointer(uintptr_t P) { - return reinterpret_cast(P); - } - static inline uintptr_t getFromVoidPointer(void *P) { - return reinterpret_cast(P); - } - // No bits are available! - enum { NumLowBitsAvailable = 0 }; -}; - -} // end namespace llvm - -#endif diff --git a/wpiutil/include/llvm/STLExtras.h b/wpiutil/include/llvm/STLExtras.h deleted file mode 100644 index 1b43f30..0000000 --- a/wpiutil/include/llvm/STLExtras.h +++ /dev/null @@ -1,521 +0,0 @@ -//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains some templates that are useful if you are working with the -// STL at all. -// -// No library is required when using these functions. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_STLEXTRAS_H -#define LLVM_ADT_STLEXTRAS_H - -#include // for std::all_of -#include -#include // for std::size_t -#include // for qsort -#include -#include -#include -#include // for std::pair - -#include "llvm/iterator_range.h" -#include "llvm/Compiler.h" - -namespace llvm { - -//===----------------------------------------------------------------------===// -// Extra additions to -//===----------------------------------------------------------------------===// - -template -struct identity : public std::unary_function { - Ty &operator()(Ty &self) const { - return self; - } - const Ty &operator()(const Ty &self) const { - return self; - } -}; - -template -struct less_ptr : public std::binary_function { - bool operator()(const Ty* left, const Ty* right) const { - return *left < *right; - } -}; - -template -struct greater_ptr : public std::binary_function { - bool operator()(const Ty* left, const Ty* right) const { - return *right < *left; - } -}; - -/// An efficient, type-erasing, non-owning reference to a callable. This is -/// intended for use as the type of a function parameter that is not used -/// after the function in question returns. -/// -/// This class does not own the callable, so it is not in general safe to store -/// a function_ref. -template class function_ref; - -template -class function_ref { - Ret (*callback)(intptr_t callable, Params ...params); - intptr_t callable; - - template - static Ret callback_fn(intptr_t callable, Params ...params) { - return (*reinterpret_cast(callable))( - std::forward(params)...); - } - -public: - template - function_ref(Callable &&callable, - typename std::enable_if< - !std::is_same::type, - function_ref>::value>::type * = nullptr) - : callback(callback_fn::type>), - callable(reinterpret_cast(&callable)) {} - Ret operator()(Params ...params) const { - return callback(callable, std::forward(params)...); - } -}; - -// deleter - Very very very simple method that is used to invoke operator -// delete on something. It is used like this: -// -// for_each(V.begin(), B.end(), deleter); -// -template -inline void deleter(T *Ptr) { - delete Ptr; -} - - - -//===----------------------------------------------------------------------===// -// Extra additions to -//===----------------------------------------------------------------------===// - -// mapped_iterator - This is a simple iterator adapter that causes a function to -// be dereferenced whenever operator* is invoked on the iterator. -// -template -class mapped_iterator { - RootIt current; - UnaryFunc Fn; -public: - typedef typename std::iterator_traits::iterator_category - iterator_category; - typedef typename std::iterator_traits::difference_type - difference_type; - typedef typename std::result_of< - UnaryFunc(decltype(*std::declval()))> - ::type value_type; - - typedef void pointer; - //typedef typename UnaryFunc::result_type *pointer; - typedef void reference; // Can't modify value returned by fn - - typedef RootIt iterator_type; - - inline const RootIt &getCurrent() const { return current; } - inline const UnaryFunc &getFunc() const { return Fn; } - - inline explicit mapped_iterator(const RootIt &I, UnaryFunc F) - : current(I), Fn(F) {} - - inline value_type operator*() const { // All this work to do this - return Fn(*current); // little change - } - - mapped_iterator &operator++() { - ++current; - return *this; - } - mapped_iterator &operator--() { - --current; - return *this; - } - mapped_iterator operator++(int) { - mapped_iterator __tmp = *this; - ++current; - return __tmp; - } - mapped_iterator operator--(int) { - mapped_iterator __tmp = *this; - --current; - return __tmp; - } - mapped_iterator operator+(difference_type n) const { - return mapped_iterator(current + n, Fn); - } - mapped_iterator &operator+=(difference_type n) { - current += n; - return *this; - } - mapped_iterator operator-(difference_type n) const { - return mapped_iterator(current - n, Fn); - } - mapped_iterator &operator-=(difference_type n) { - current -= n; - return *this; - } - reference operator[](difference_type n) const { return *(*this + n); } - - bool operator!=(const mapped_iterator &X) const { return !operator==(X); } - bool operator==(const mapped_iterator &X) const { - return current == X.current; - } - bool operator<(const mapped_iterator &X) const { return current < X.current; } - - difference_type operator-(const mapped_iterator &X) const { - return current - X.current; - } -}; - -template -inline mapped_iterator -operator+(typename mapped_iterator::difference_type N, - const mapped_iterator &X) { - return mapped_iterator(X.getCurrent() - N, X.getFunc()); -} - - -// map_iterator - Provide a convenient way to create mapped_iterators, just like -// make_pair is useful for creating pairs... -// -template -inline mapped_iterator map_iterator(const ItTy &I, FuncTy F) { - return mapped_iterator(I, F); -} - -/// \brief Metafunction to determine if type T has a member called rbegin(). -template struct has_rbegin { - template static char(&f(const U &, decltype(&U::rbegin)))[1]; - static char(&f(...))[2]; - const static bool value = sizeof(f(std::declval(), nullptr)) == 1; -}; - -// Returns an iterator_range over the given container which iterates in reverse. -// Note that the container must have rbegin()/rend() methods for this to work. -template -auto reverse(ContainerTy &&C, - typename std::enable_if::value>::type * = - nullptr) -> decltype(make_range(C.rbegin(), C.rend())) { - return make_range(C.rbegin(), C.rend()); -} - -// Returns a std::reverse_iterator wrapped around the given iterator. -template -std::reverse_iterator make_reverse_iterator(IteratorTy It) { - return std::reverse_iterator(It); -} - -// Returns an iterator_range over the given container which iterates in reverse. -// Note that the container must have begin()/end() methods which return -// bidirectional iterators for this to work. -template -auto reverse( - ContainerTy &&C, - typename std::enable_if::value>::type * = nullptr) - -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)), - llvm::make_reverse_iterator(std::begin(C)))) { - return make_range(llvm::make_reverse_iterator(std::end(C)), - llvm::make_reverse_iterator(std::begin(C))); -} - -//===----------------------------------------------------------------------===// -// Extra additions to -//===----------------------------------------------------------------------===// - -/// \brief Function object to check whether the first component of a std::pair -/// compares less than the first component of another std::pair. -struct less_first { - template bool operator()(const T &lhs, const T &rhs) const { - return lhs.first < rhs.first; - } -}; - -/// \brief Function object to check whether the second component of a std::pair -/// compares less than the second component of another std::pair. -struct less_second { - template bool operator()(const T &lhs, const T &rhs) const { - return lhs.second < rhs.second; - } -}; - -// A subset of N3658. More stuff can be added as-needed. - -/// \brief Represents a compile-time sequence of integers. -template struct integer_sequence { - typedef T value_type; - - static LLVM_CONSTEXPR size_t size() { return sizeof...(I); } -}; - -/// \brief Alias for the common case of a sequence of size_ts. -template -struct index_sequence : integer_sequence {}; - -template -struct build_index_impl : build_index_impl {}; -template -struct build_index_impl<0, I...> : index_sequence {}; - -/// \brief Creates a compile-time integer sequence for a parameter pack. -template -struct index_sequence_for : build_index_impl {}; - -//===----------------------------------------------------------------------===// -// Extra additions for arrays -//===----------------------------------------------------------------------===// - -/// Find the length of an array. -template -LLVM_CONSTEXPR inline size_t array_lengthof(T (&)[N]) { - return N; -} - -/// Adapt std::less for array_pod_sort. -template -inline int array_pod_sort_comparator(const void *P1, const void *P2) { - if (std::less()(*reinterpret_cast(P1), - *reinterpret_cast(P2))) - return -1; - if (std::less()(*reinterpret_cast(P2), - *reinterpret_cast(P1))) - return 1; - return 0; -} - -/// get_array_pod_sort_comparator - This is an internal helper function used to -/// get type deduction of T right. -template -inline int (*get_array_pod_sort_comparator(const T &)) - (const void*, const void*) { - return array_pod_sort_comparator; -} - - -/// array_pod_sort - This sorts an array with the specified start and end -/// extent. This is just like std::sort, except that it calls qsort instead of -/// using an inlined template. qsort is slightly slower than std::sort, but -/// most sorts are not performance critical in LLVM and std::sort has to be -/// template instantiated for each type, leading to significant measured code -/// bloat. This function should generally be used instead of std::sort where -/// possible. -/// -/// This function assumes that you have simple POD-like types that can be -/// compared with std::less and can be moved with memcpy. If this isn't true, -/// you should use std::sort. -/// -/// NOTE: If qsort_r were portable, we could allow a custom comparator and -/// default to std::less. -template -inline void array_pod_sort(IteratorTy Start, IteratorTy End) { - // Don't inefficiently call qsort with one element or trigger undefined - // behavior with an empty sequence. - auto NElts = End - Start; - if (NElts <= 1) return; - qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start)); -} - -template -inline void array_pod_sort( - IteratorTy Start, IteratorTy End, - int (*Compare)( - const typename std::iterator_traits::value_type *, - const typename std::iterator_traits::value_type *)) { - // Don't inefficiently call qsort with one element or trigger undefined - // behavior with an empty sequence. - auto NElts = End - Start; - if (NElts <= 1) return; - qsort(&*Start, NElts, sizeof(*Start), - reinterpret_cast(Compare)); -} - -//===----------------------------------------------------------------------===// -// Extra additions to -//===----------------------------------------------------------------------===// - -/// For a container of pointers, deletes the pointers and then clears the -/// container. -template -void DeleteContainerPointers(Container &C) { - for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I) - delete *I; - C.clear(); -} - -/// In a container of pairs (usually a map) whose second element is a pointer, -/// deletes the second elements and then clears the container. -template -void DeleteContainerSeconds(Container &C) { - for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I) - delete I->second; - C.clear(); -} - -/// Provide wrappers to std::all_of which take ranges instead of having to pass -/// begin/end explicitly. -template -bool all_of(R &&Range, UnaryPredicate &&P) { - return std::all_of(Range.begin(), Range.end(), - std::forward(P)); -} - -/// Provide wrappers to std::any_of which take ranges instead of having to pass -/// begin/end explicitly. -template -bool any_of(R &&Range, UnaryPredicate &&P) { - return std::any_of(Range.begin(), Range.end(), - std::forward(P)); -} - -/// Provide wrappers to std::none_of which take ranges instead of having to pass -/// begin/end explicitly. -template -bool none_of(R &&Range, UnaryPredicate &&P) { - return std::none_of(Range.begin(), Range.end(), - std::forward(P)); -} - -/// Provide wrappers to std::find which take ranges instead of having to pass -/// begin/end explicitly. -template -auto find(R &&Range, const T &val) -> decltype(Range.begin()) { - return std::find(Range.begin(), Range.end(), val); -} - -/// Provide wrappers to std::find_if which take ranges instead of having to pass -/// begin/end explicitly. -template -auto find_if(R &&Range, const T &Pred) -> decltype(Range.begin()) { - return std::find_if(Range.begin(), Range.end(), Pred); -} - -/// Provide wrappers to std::remove_if which take ranges instead of having to -/// pass begin/end explicitly. -template -auto remove_if(R &&Range, UnaryPredicate &&P) -> decltype(Range.begin()) { - return std::remove_if(Range.begin(), Range.end(), P); -} - -/// Wrapper function around std::find to detect if an element exists -/// in a container. -template -bool is_contained(R &&Range, const E &Element) { - return std::find(Range.begin(), Range.end(), Element) != Range.end(); -} - -/// Wrapper function around std::count_if to count the number of times an -/// element satisfying a given predicate occurs in a range. -template -auto count_if(R &&Range, UnaryPredicate &&P) - -> typename std::iterator_traits::difference_type { - return std::count_if(Range.begin(), Range.end(), P); -} - -/// Wrapper function around std::transform to apply a function to a range and -/// store the result elsewhere. -template -OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate &&P) { - return std::transform(Range.begin(), Range.end(), d_first, - std::forward(P)); -} - -//===----------------------------------------------------------------------===// -// Extra additions to -//===----------------------------------------------------------------------===// - -// Implement make_unique according to N3656. - -/// \brief Constructs a `new T()` with the given args and returns a -/// `unique_ptr` which owns the object. -/// -/// Example: -/// -/// auto p = make_unique(); -/// auto p = make_unique>(0, 1); -template -typename std::enable_if::value, std::unique_ptr>::type -make_unique(Args &&... args) { - return std::unique_ptr(new T(std::forward(args)...)); -} - -/// \brief Constructs a `new T[n]` with the given args and returns a -/// `unique_ptr` which owns the object. -/// -/// \param n size of the new array. -/// -/// Example: -/// -/// auto p = make_unique(2); // value-initializes the array with 0's. -template -typename std::enable_if::value && std::extent::value == 0, - std::unique_ptr>::type -make_unique(size_t n) { - return std::unique_ptr(new typename std::remove_extent::type[n]()); -} - -/// This function isn't used and is only here to provide better compile errors. -template -typename std::enable_if::value != 0>::type -make_unique(Args &&...) = delete; - -struct FreeDeleter { - void operator()(void* v) { - ::free(v); - } -}; - -template -struct pair_hash { - size_t operator()(const std::pair &P) const { - return std::hash()(P.first) * 31 + std::hash()(P.second); - } -}; - -/// A functor like C++14's std::less in its absence. -struct less { - template bool operator()(A &&a, B &&b) const { - return std::forward(a) < std::forward(b); - } -}; - -/// A functor like C++14's std::equal in its absence. -struct equal { - template bool operator()(A &&a, B &&b) const { - return std::forward(a) == std::forward(b); - } -}; - -/// Binary functor that adapts to any other binary functor after dereferencing -/// operands. -template struct deref { - T func; - // Could be further improved to cope with non-derivable functors and - // non-binary functors (should be a variadic template member function - // operator()). - template - auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) { - assert(lhs); - assert(rhs); - return func(*lhs, *rhs); - } -}; - -} // End llvm namespace - -#endif diff --git a/wpiutil/include/llvm/SmallPtrSet.h b/wpiutil/include/llvm/SmallPtrSet.h deleted file mode 100644 index b78e1fd..0000000 --- a/wpiutil/include/llvm/SmallPtrSet.h +++ /dev/null @@ -1,406 +0,0 @@ -//===- llvm/ADT/SmallPtrSet.h - 'Normally small' pointer set ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the SmallPtrSet class. See the doxygen comment for -// SmallPtrSetImplBase for more details on the algorithm used. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_SMALLPTRSET_H -#define LLVM_ADT_SMALLPTRSET_H - -#include "llvm/Compiler.h" -#include "llvm/PointerLikeTypeTraits.h" -#include -#include -#include -#include -#include -#include -#include - -namespace llvm { - -class SmallPtrSetIteratorImpl; - -/// SmallPtrSetImplBase - This is the common code shared among all the -/// SmallPtrSet<>'s, which is almost everything. SmallPtrSet has two modes, one -/// for small and one for large sets. -/// -/// Small sets use an array of pointers allocated in the SmallPtrSet object, -/// which is treated as a simple array of pointers. When a pointer is added to -/// the set, the array is scanned to see if the element already exists, if not -/// the element is 'pushed back' onto the array. If we run out of space in the -/// array, we grow into the 'large set' case. SmallSet should be used when the -/// sets are often small. In this case, no memory allocation is used, and only -/// light-weight and cache-efficient scanning is used. -/// -/// Large sets use a classic exponentially-probed hash table. Empty buckets are -/// represented with an illegal pointer value (-1) to allow null pointers to be -/// inserted. Tombstones are represented with another illegal pointer value -/// (-2), to allow deletion. The hash table is resized when the table is 3/4 or -/// more. When this happens, the table is doubled in size. -/// -class SmallPtrSetImplBase { - friend class SmallPtrSetIteratorImpl; - -protected: - /// SmallArray - Points to a fixed size set of buckets, used in 'small mode'. - const void **SmallArray; - /// CurArray - This is the current set of buckets. If equal to SmallArray, - /// then the set is in 'small mode'. - const void **CurArray; - /// CurArraySize - The allocated size of CurArray, always a power of two. - unsigned CurArraySize; - - /// Number of elements in CurArray that contain a value or are a tombstone. - /// If small, all these elements are at the beginning of CurArray and the rest - /// is uninitialized. - unsigned NumNonEmpty; - /// Number of tombstones in CurArray. - unsigned NumTombstones; - - // Helpers to copy and move construct a SmallPtrSet. - SmallPtrSetImplBase(const void **SmallStorage, - const SmallPtrSetImplBase &that); - SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize, - SmallPtrSetImplBase &&that); - explicit SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize) - : SmallArray(SmallStorage), CurArray(SmallStorage), - CurArraySize(SmallSize), NumNonEmpty(0), NumTombstones(0) { - assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 && - "Initial size must be a power of two!"); - } - ~SmallPtrSetImplBase() { - if (!isSmall()) - free(CurArray); - } - -public: - typedef unsigned size_type; - bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return size() == 0; } - size_type size() const { return NumNonEmpty - NumTombstones; } - - void clear() { - // If the capacity of the array is huge, and the # elements used is small, - // shrink the array. - if (!isSmall()) { - if (size() * 4 < CurArraySize && CurArraySize > 32) - return shrink_and_clear(); - // Fill the array with empty markers. - memset(CurArray, -1, CurArraySize * sizeof(void *)); - } - - NumNonEmpty = 0; - NumTombstones = 0; - } - -protected: - static void *getTombstoneMarker() { return reinterpret_cast(-2); } - static void *getEmptyMarker() { - // Note that -1 is chosen to make clear() efficiently implementable with - // memset and because it's not a valid pointer value. - return reinterpret_cast(-1); - } - - const void **EndPointer() const { - return isSmall() ? CurArray + NumNonEmpty : CurArray + CurArraySize; - } - - /// insert_imp - This returns true if the pointer was new to the set, false if - /// it was already in the set. This is hidden from the client so that the - /// derived class can check that the right type of pointer is passed in. - std::pair insert_imp(const void *Ptr) { - if (isSmall()) { - // Check to see if it is already in the set. - const void **LastTombstone = nullptr; - for (const void **APtr = SmallArray, **E = SmallArray + NumNonEmpty; - APtr != E; ++APtr) { - const void *Value = *APtr; - if (Value == Ptr) - return std::make_pair(APtr, false); - if (Value == getTombstoneMarker()) - LastTombstone = APtr; - } - - // Did we find any tombstone marker? - if (LastTombstone != nullptr) { - *LastTombstone = Ptr; - --NumTombstones; - return std::make_pair(LastTombstone, true); - } - - // Nope, there isn't. If we stay small, just 'pushback' now. - if (NumNonEmpty < CurArraySize) { - SmallArray[NumNonEmpty++] = Ptr; - return std::make_pair(SmallArray + (NumNonEmpty - 1), true); - } - // Otherwise, hit the big set case, which will call grow. - } - return insert_imp_big(Ptr); - } - - /// erase_imp - If the set contains the specified pointer, remove it and - /// return true, otherwise return false. This is hidden from the client so - /// that the derived class can check that the right type of pointer is passed - /// in. - bool erase_imp(const void * Ptr); - - bool count_imp(const void * Ptr) const { - if (isSmall()) { - // Linear search for the item. - for (const void *const *APtr = SmallArray, - *const *E = SmallArray + NumNonEmpty; APtr != E; ++APtr) - if (*APtr == Ptr) - return true; - return false; - } - - // Big set case. - return *FindBucketFor(Ptr) == Ptr; - } - -private: - bool isSmall() const { return CurArray == SmallArray; } - - std::pair insert_imp_big(const void *Ptr); - - const void * const *FindBucketFor(const void *Ptr) const; - void shrink_and_clear(); - - /// Grow - Allocate a larger backing store for the buckets and move it over. - void Grow(unsigned NewSize); - - void operator=(const SmallPtrSetImplBase &RHS) = delete; - -protected: - /// swap - Swaps the elements of two sets. - /// Note: This method assumes that both sets have the same small size. - void swap(SmallPtrSetImplBase &RHS); - - void CopyFrom(const SmallPtrSetImplBase &RHS); - void MoveFrom(unsigned SmallSize, SmallPtrSetImplBase &&RHS); - -private: - /// Code shared by MoveFrom() and move constructor. - void MoveHelper(unsigned SmallSize, SmallPtrSetImplBase &&RHS); - /// Code shared by CopyFrom() and copy constructor. - void CopyHelper(const SmallPtrSetImplBase &RHS); -}; - -/// SmallPtrSetIteratorImpl - This is the common base class shared between all -/// instances of SmallPtrSetIterator. -class SmallPtrSetIteratorImpl { -protected: - const void *const *Bucket; - const void *const *End; - -public: - explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E) - : Bucket(BP), End(E) { - AdvanceIfNotValid(); - } - - bool operator==(const SmallPtrSetIteratorImpl &RHS) const { - return Bucket == RHS.Bucket; - } - bool operator!=(const SmallPtrSetIteratorImpl &RHS) const { - return Bucket != RHS.Bucket; - } - -protected: - /// AdvanceIfNotValid - If the current bucket isn't valid, advance to a bucket - /// that is. This is guaranteed to stop because the end() bucket is marked - /// valid. - void AdvanceIfNotValid() { - assert(Bucket <= End); - while (Bucket != End && - (*Bucket == SmallPtrSetImplBase::getEmptyMarker() || - *Bucket == SmallPtrSetImplBase::getTombstoneMarker())) - ++Bucket; - } -}; - -/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet. -template -class SmallPtrSetIterator : public SmallPtrSetIteratorImpl { - typedef PointerLikeTypeTraits PtrTraits; - -public: - typedef PtrTy value_type; - typedef PtrTy reference; - typedef PtrTy pointer; - typedef std::ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; - - explicit SmallPtrSetIterator(const void *const *BP, const void *const *E) - : SmallPtrSetIteratorImpl(BP, E) {} - - // Most methods provided by baseclass. - - const PtrTy operator*() const { - assert(Bucket < End); - return PtrTraits::getFromVoidPointer(const_cast(*Bucket)); - } - - inline SmallPtrSetIterator& operator++() { // Preincrement - ++Bucket; - AdvanceIfNotValid(); - return *this; - } - - SmallPtrSetIterator operator++(int) { // Postincrement - SmallPtrSetIterator tmp = *this; ++*this; return tmp; - } -}; - -/// RoundUpToPowerOfTwo - This is a helper template that rounds N up to the next -/// power of two (which means N itself if N is already a power of two). -template -struct RoundUpToPowerOfTwo; - -/// RoundUpToPowerOfTwoH - If N is not a power of two, increase it. This is a -/// helper template used to implement RoundUpToPowerOfTwo. -template -struct RoundUpToPowerOfTwoH { - enum { Val = N }; -}; -template -struct RoundUpToPowerOfTwoH { - enum { - // We could just use NextVal = N+1, but this converges faster. N|(N-1) sets - // the right-most zero bits to one all at once, e.g. 0b0011000 -> 0b0011111. - Val = RoundUpToPowerOfTwo<(N|(N-1)) + 1>::Val - }; -}; - -template -struct RoundUpToPowerOfTwo { - enum { Val = RoundUpToPowerOfTwoH::Val }; -}; - -/// \brief A templated base class for \c SmallPtrSet which provides the -/// typesafe interface that is common across all small sizes. -/// -/// This is particularly useful for passing around between interface boundaries -/// to avoid encoding a particular small size in the interface boundary. -template -class SmallPtrSetImpl : public SmallPtrSetImplBase { - typedef PointerLikeTypeTraits PtrTraits; - - SmallPtrSetImpl(const SmallPtrSetImpl &) = delete; - -protected: - // Constructors that forward to the base. - SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl &that) - : SmallPtrSetImplBase(SmallStorage, that) {} - SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize, - SmallPtrSetImpl &&that) - : SmallPtrSetImplBase(SmallStorage, SmallSize, std::move(that)) {} - explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize) - : SmallPtrSetImplBase(SmallStorage, SmallSize) {} - -public: - typedef SmallPtrSetIterator iterator; - typedef SmallPtrSetIterator const_iterator; - - /// Inserts Ptr if and only if there is no element in the container equal to - /// Ptr. The bool component of the returned pair is true if and only if the - /// insertion takes place, and the iterator component of the pair points to - /// the element equal to Ptr. - std::pair insert(PtrType Ptr) { - auto p = insert_imp(PtrTraits::getAsVoidPointer(Ptr)); - return std::make_pair(iterator(p.first, EndPointer()), p.second); - } - - /// erase - If the set contains the specified pointer, remove it and return - /// true, otherwise return false. - bool erase(PtrType Ptr) { - return erase_imp(PtrTraits::getAsVoidPointer(Ptr)); - } - - /// count - Return 1 if the specified pointer is in the set, 0 otherwise. - size_type count(PtrType Ptr) const { - return count_imp(PtrTraits::getAsVoidPointer(Ptr)) ? 1 : 0; - } - - template - void insert(IterT I, IterT E) { - for (; I != E; ++I) - insert(*I); - } - - inline iterator begin() const { - return iterator(CurArray, EndPointer()); - } - inline iterator end() const { - const void *const *End = EndPointer(); - return iterator(End, End); - } -}; - -/// SmallPtrSet - This class implements a set which is optimized for holding -/// SmallSize or less elements. This internally rounds up SmallSize to the next -/// power of two if it is not already a power of two. See the comments above -/// SmallPtrSetImplBase for details of the algorithm. -template -class SmallPtrSet : public SmallPtrSetImpl { - // In small mode SmallPtrSet uses linear search for the elements, so it is - // not a good idea to choose this value too high. You may consider using a - // DenseSet<> instead if you expect many elements in the set. - static_assert(SmallSize <= 32, "SmallSize should be small"); - - typedef SmallPtrSetImpl BaseT; - - // Make sure that SmallSize is a power of two, round up if not. - enum { SmallSizePowTwo = RoundUpToPowerOfTwo::Val }; - /// SmallStorage - Fixed size storage used in 'small mode'. - const void *SmallStorage[SmallSizePowTwo]; - -public: - SmallPtrSet() : BaseT(SmallStorage, SmallSizePowTwo) {} - SmallPtrSet(const SmallPtrSet &that) : BaseT(SmallStorage, that) {} - SmallPtrSet(SmallPtrSet &&that) - : BaseT(SmallStorage, SmallSizePowTwo, std::move(that)) {} - - template - SmallPtrSet(It I, It E) : BaseT(SmallStorage, SmallSizePowTwo) { - this->insert(I, E); - } - - SmallPtrSet & - operator=(const SmallPtrSet &RHS) { - if (&RHS != this) - this->CopyFrom(RHS); - return *this; - } - - SmallPtrSet& - operator=(SmallPtrSet &&RHS) { - if (&RHS != this) - this->MoveFrom(SmallSizePowTwo, std::move(RHS)); - return *this; - } - - /// swap - Swaps the elements of two sets. - void swap(SmallPtrSet &RHS) { - SmallPtrSetImplBase::swap(RHS); - } -}; -} - -namespace std { - /// Implement std::swap in terms of SmallPtrSet swap. - template - inline void swap(llvm::SmallPtrSet &LHS, llvm::SmallPtrSet &RHS) { - LHS.swap(RHS); - } -} - -#endif diff --git a/wpiutil/include/llvm/SmallSet.h b/wpiutil/include/llvm/SmallSet.h deleted file mode 100644 index 3dfd1f9..0000000 --- a/wpiutil/include/llvm/SmallSet.h +++ /dev/null @@ -1,136 +0,0 @@ -//===- llvm/ADT/SmallSet.h - 'Normally small' sets --------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the SmallSet class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_SMALLSET_H -#define LLVM_ADT_SMALLSET_H - -#include "llvm/None.h" -#include "llvm/SmallPtrSet.h" -#include "llvm/SmallVector.h" -#include - -namespace llvm { - -/// SmallSet - This maintains a set of unique values, optimizing for the case -/// when the set is small (less than N). In this case, the set can be -/// maintained with no mallocs. If the set gets large, we expand to using an -/// std::set to maintain reasonable lookup times. -/// -/// Note that this set does not provide a way to iterate over members in the -/// set. -template > -class SmallSet { - /// Use a SmallVector to hold the elements here (even though it will never - /// reach its 'large' stage) to avoid calling the default ctors of elements - /// we will never use. - SmallVector Vector; - std::set Set; - typedef typename SmallVector::const_iterator VIterator; - typedef typename SmallVector::iterator mutable_iterator; - - // In small mode SmallPtrSet uses linear search for the elements, so it is - // not a good idea to choose this value too high. You may consider using a - // DenseSet<> instead if you expect many elements in the set. - static_assert(N <= 32, "N should be small"); - -public: - typedef size_t size_type; - SmallSet() {} - - bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { - return Vector.empty() && Set.empty(); - } - - size_type size() const { - return isSmall() ? Vector.size() : Set.size(); - } - - /// count - Return 1 if the element is in the set, 0 otherwise. - size_type count(const T &V) const { - if (isSmall()) { - // Since the collection is small, just do a linear search. - return vfind(V) == Vector.end() ? 0 : 1; - } else { - return Set.count(V); - } - } - - /// insert - Insert an element into the set if it isn't already there. - /// Returns true if the element is inserted (it was not in the set before). - /// The first value of the returned pair is unused and provided for - /// partial compatibility with the standard library self-associative container - /// concept. - // FIXME: Add iterators that abstract over the small and large form, and then - // return those here. - std::pair insert(const T &V) { - if (!isSmall()) - return std::make_pair(None, Set.insert(V).second); - - VIterator I = vfind(V); - if (I != Vector.end()) // Don't reinsert if it already exists. - return std::make_pair(None, false); - if (Vector.size() < N) { - Vector.push_back(V); - return std::make_pair(None, true); - } - - // Otherwise, grow from vector to set. - while (!Vector.empty()) { - Set.insert(Vector.back()); - Vector.pop_back(); - } - Set.insert(V); - return std::make_pair(None, true); - } - - template - void insert(IterT I, IterT E) { - for (; I != E; ++I) - insert(*I); - } - - bool erase(const T &V) { - if (!isSmall()) - return Set.erase(V); - for (mutable_iterator I = Vector.begin(), E = Vector.end(); I != E; ++I) - if (*I == V) { - Vector.erase(I); - return true; - } - return false; - } - - void clear() { - Vector.clear(); - Set.clear(); - } - -private: - bool isSmall() const { return Set.empty(); } - - VIterator vfind(const T &V) const { - for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I) - if (*I == V) - return I; - return Vector.end(); - } -}; - -/// If this set is of pointer values, transparently switch over to using -/// SmallPtrSet for performance. -template -class SmallSet : public SmallPtrSet {}; - -} // end namespace llvm - -#endif diff --git a/wpiutil/include/llvm/SmallString.h b/wpiutil/include/llvm/SmallString.h deleted file mode 100644 index 4c60c9b..0000000 --- a/wpiutil/include/llvm/SmallString.h +++ /dev/null @@ -1,297 +0,0 @@ -//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the SmallString class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_SMALLSTRING_H -#define LLVM_ADT_SMALLSTRING_H - -#include "llvm/SmallVector.h" -#include "llvm/StringRef.h" - -namespace llvm { - -/// SmallString - A SmallString is just a SmallVector with methods and accessors -/// that make it work better as a string (e.g. operator+ etc). -template -class SmallString : public SmallVector { -public: - /// Default ctor - Initialize to empty. - SmallString() {} - - /// Initialize from a StringRef. - SmallString(StringRef S) : SmallVector(S.begin(), S.end()) {} - - /// Initialize with a range. - template - SmallString(ItTy S, ItTy E) : SmallVector(S, E) {} - - // Note that in order to add new overloads for append & assign, we have to - // duplicate the inherited versions so as not to inadvertently hide them. - - /// @} - /// @name String Assignment - /// @{ - - /// Assign from a repeated element. - void assign(size_t NumElts, char Elt) { - this->SmallVectorImpl::assign(NumElts, Elt); - } - - /// Assign from an iterator pair. - template - void assign(in_iter S, in_iter E) { - this->clear(); - SmallVectorImpl::append(S, E); - } - - /// Assign from a StringRef. - void assign(StringRef RHS) { - this->clear(); - SmallVectorImpl::append(RHS.begin(), RHS.end()); - } - - /// Assign from a SmallVector. - void assign(const SmallVectorImpl &RHS) { - this->clear(); - SmallVectorImpl::append(RHS.begin(), RHS.end()); - } - - /// @} - /// @name String Concatenation - /// @{ - - /// Append from an iterator pair. - template - void append(in_iter S, in_iter E) { - SmallVectorImpl::append(S, E); - } - - void append(size_t NumInputs, char Elt) { - SmallVectorImpl::append(NumInputs, Elt); - } - - - /// Append from a StringRef. - void append(StringRef RHS) { - SmallVectorImpl::append(RHS.begin(), RHS.end()); - } - - /// Append from a SmallVector. - void append(const SmallVectorImpl &RHS) { - SmallVectorImpl::append(RHS.begin(), RHS.end()); - } - - /// @} - /// @name String Comparison - /// @{ - - /// Check for string equality. This is more efficient than compare() when - /// the relative ordering of inequal strings isn't needed. - bool equals(StringRef RHS) const { - return str().equals(RHS); - } - - /// Check for string equality, ignoring case. - bool equals_lower(StringRef RHS) const { - return str().equals_lower(RHS); - } - - /// Compare two strings; the result is -1, 0, or 1 if this string is - /// lexicographically less than, equal to, or greater than the \p RHS. - int compare(StringRef RHS) const { - return str().compare(RHS); - } - - /// compare_lower - Compare two strings, ignoring case. - int compare_lower(StringRef RHS) const { - return str().compare_lower(RHS); - } - - /// compare_numeric - Compare two strings, treating sequences of digits as - /// numbers. - int compare_numeric(StringRef RHS) const { - return str().compare_numeric(RHS); - } - - /// @} - /// @name String Predicates - /// @{ - - /// startswith - Check if this string starts with the given \p Prefix. - bool startswith(StringRef Prefix) const { - return str().startswith(Prefix); - } - - /// endswith - Check if this string ends with the given \p Suffix. - bool endswith(StringRef Suffix) const { - return str().endswith(Suffix); - } - - /// @} - /// @name String Searching - /// @{ - - /// find - Search for the first character \p C in the string. - /// - /// \return - The index of the first occurrence of \p C, or npos if not - /// found. - size_t find(char C, size_t From = 0) const { - return str().find(C, From); - } - - /// Search for the first string \p Str in the string. - /// - /// \returns The index of the first occurrence of \p Str, or npos if not - /// found. - size_t find(StringRef Str, size_t From = 0) const { - return str().find(Str, From); - } - - /// Search for the last character \p C in the string. - /// - /// \returns The index of the last occurrence of \p C, or npos if not - /// found. - size_t rfind(char C, size_t From = StringRef::npos) const { - return str().rfind(C, From); - } - - /// Search for the last string \p Str in the string. - /// - /// \returns The index of the last occurrence of \p Str, or npos if not - /// found. - size_t rfind(StringRef Str) const { - return str().rfind(Str); - } - - /// Find the first character in the string that is \p C, or npos if not - /// found. Same as find. - size_t find_first_of(char C, size_t From = 0) const { - return str().find_first_of(C, From); - } - - /// Find the first character in the string that is in \p Chars, or npos if - /// not found. - /// - /// Complexity: O(size() + Chars.size()) - size_t find_first_of(StringRef Chars, size_t From = 0) const { - return str().find_first_of(Chars, From); - } - - /// Find the first character in the string that is not \p C or npos if not - /// found. - size_t find_first_not_of(char C, size_t From = 0) const { - return str().find_first_not_of(C, From); - } - - /// Find the first character in the string that is not in the string - /// \p Chars, or npos if not found. - /// - /// Complexity: O(size() + Chars.size()) - size_t find_first_not_of(StringRef Chars, size_t From = 0) const { - return str().find_first_not_of(Chars, From); - } - - /// Find the last character in the string that is \p C, or npos if not - /// found. - size_t find_last_of(char C, size_t From = StringRef::npos) const { - return str().find_last_of(C, From); - } - - /// Find the last character in the string that is in \p C, or npos if not - /// found. - /// - /// Complexity: O(size() + Chars.size()) - size_t find_last_of( - StringRef Chars, size_t From = StringRef::npos) const { - return str().find_last_of(Chars, From); - } - - /// @} - /// @name Helpful Algorithms - /// @{ - - /// Return the number of occurrences of \p C in the string. - size_t count(char C) const { - return str().count(C); - } - - /// Return the number of non-overlapped occurrences of \p Str in the - /// string. - size_t count(StringRef Str) const { - return str().count(Str); - } - - /// @} - /// @name Substring Operations - /// @{ - - /// Return a reference to the substring from [Start, Start + N). - /// - /// \param Start The index of the starting character in the substring; if - /// the index is npos or greater than the length of the string then the - /// empty substring will be returned. - /// - /// \param N The number of characters to included in the substring. If \p N - /// exceeds the number of characters remaining in the string, the string - /// suffix (starting with \p Start) will be returned. - StringRef substr(size_t Start, size_t N = StringRef::npos) const { - return str().substr(Start, N); - } - - /// Return a reference to the substring from [Start, End). - /// - /// \param Start The index of the starting character in the substring; if - /// the index is npos or greater than the length of the string then the - /// empty substring will be returned. - /// - /// \param End The index following the last character to include in the - /// substring. If this is npos, or less than \p Start, or exceeds the - /// number of characters remaining in the string, the string suffix - /// (starting with \p Start) will be returned. - StringRef slice(size_t Start, size_t End) const { - return str().slice(Start, End); - } - - // Extra methods. - - /// Explicit conversion to StringRef. - StringRef str() const { return StringRef(this->begin(), this->size()); } - - // TODO: Make this const, if it's safe... - const char* c_str() { - this->push_back(0); - this->pop_back(); - return this->data(); - } - - /// Implicit conversion to StringRef. - operator StringRef() const { return str(); } - - // Extra operators. - const SmallString &operator=(StringRef RHS) { - this->clear(); - return *this += RHS; - } - - SmallString &operator+=(StringRef RHS) { - this->append(RHS.begin(), RHS.end()); - return *this; - } - SmallString &operator+=(char C) { - this->push_back(C); - return *this; - } -}; - -} - -#endif diff --git a/wpiutil/include/llvm/SmallVector.h b/wpiutil/include/llvm/SmallVector.h deleted file mode 100644 index 0f9c73b..0000000 --- a/wpiutil/include/llvm/SmallVector.h +++ /dev/null @@ -1,920 +0,0 @@ -//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the SmallVector class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_SMALLVECTOR_H -#define LLVM_ADT_SMALLVECTOR_H - -#include "llvm/iterator_range.h" -#include "llvm/AlignOf.h" -#include "llvm/Compiler.h" -#include "llvm/MathExtras.h" -#include "llvm/type_traits.h" -#include -#include -#include -#include -#include -#include -#include -#include - -namespace llvm { - -/// This is all the non-templated stuff common to all SmallVectors. -class SmallVectorBase { -protected: - void *BeginX, *EndX, *CapacityX; - -protected: - SmallVectorBase(void *FirstEl, size_t Size) - : BeginX(FirstEl), EndX(FirstEl), CapacityX((char*)FirstEl+Size) {} - - /// This is an implementation of the grow() method which only works - /// on POD-like data types and is out of line to reduce code duplication. - void grow_pod(void *FirstEl, size_t MinSizeInBytes, size_t TSize); - -public: - /// This returns size()*sizeof(T). - size_t size_in_bytes() const { - return size_t((char*)EndX - (char*)BeginX); - } - - /// capacity_in_bytes - This returns capacity()*sizeof(T). - size_t capacity_in_bytes() const { - return size_t((char*)CapacityX - (char*)BeginX); - } - - bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return BeginX == EndX; } -}; - -template struct SmallVectorStorage; - -/// This is the part of SmallVectorTemplateBase which does not depend on whether -/// the type T is a POD. The extra dummy template argument is used by ArrayRef -/// to avoid unnecessarily requiring T to be complete. -template -class SmallVectorTemplateCommon : public SmallVectorBase { -private: - template friend struct SmallVectorStorage; - - // Allocate raw space for N elements of type T. If T has a ctor or dtor, we - // don't want it to be automatically run, so we need to represent the space as - // something else. Use an array of char of sufficient alignment. - typedef llvm::AlignedCharArrayUnion U; - U FirstEl; - // Space after 'FirstEl' is clobbered, do not add any instance vars after it. - -protected: - SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(&FirstEl, Size) {} - - void grow_pod(size_t MinSizeInBytes, size_t TSize) { - SmallVectorBase::grow_pod(&FirstEl, MinSizeInBytes, TSize); - } - - /// Return true if this is a smallvector which has not had dynamic - /// memory allocated for it. - bool isSmall() const { - return BeginX == static_cast(&FirstEl); - } - - /// Put this vector in a state of being small. - void resetToSmall() { - BeginX = EndX = CapacityX = &FirstEl; - } - - void setEnd(T *P) { this->EndX = P; } -public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T value_type; - typedef T *iterator; - typedef const T *const_iterator; - - typedef std::reverse_iterator const_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; - - typedef T &reference; - typedef const T &const_reference; - typedef T *pointer; - typedef const T *const_pointer; - - // forward iterator creation methods. - iterator begin() { return (iterator)this->BeginX; } - const_iterator begin() const { return (const_iterator)this->BeginX; } - iterator end() { return (iterator)this->EndX; } - const_iterator end() const { return (const_iterator)this->EndX; } -protected: - iterator capacity_ptr() { return (iterator)this->CapacityX; } - const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;} -public: - - // reverse iterator creation methods. - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { return const_reverse_iterator(begin());} - - size_type size() const { return end()-begin(); } - size_type max_size() const { return size_type(-1) / sizeof(T); } - - /// Return the total number of elements in the currently allocated buffer. - size_t capacity() const { return capacity_ptr() - begin(); } - - /// Return a pointer to the vector's buffer, even if empty(). - pointer data() { return pointer(begin()); } - /// Return a pointer to the vector's buffer, even if empty(). - const_pointer data() const { return const_pointer(begin()); } - - reference operator[](size_type idx) { - assert(idx < size()); - return begin()[idx]; - } - const_reference operator[](size_type idx) const { - assert(idx < size()); - return begin()[idx]; - } - - reference front() { - assert(!empty()); - return begin()[0]; - } - const_reference front() const { - assert(!empty()); - return begin()[0]; - } - - reference back() { - assert(!empty()); - return end()[-1]; - } - const_reference back() const { - assert(!empty()); - return end()[-1]; - } -}; - -/// SmallVectorTemplateBase - This is where we put method -/// implementations that are designed to work with non-POD-like T's. -template -class SmallVectorTemplateBase : public SmallVectorTemplateCommon { -protected: - SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} - - static void destroy_range(T *S, T *E) { - while (S != E) { - --E; - E->~T(); - } - } - - /// Move the range [I, E) into the uninitialized memory starting with "Dest", - /// constructing elements as needed. - template - static void uninitialized_move(It1 I, It1 E, It2 Dest) { - std::uninitialized_copy(std::make_move_iterator(I), - std::make_move_iterator(E), Dest); - } - - /// Copy the range [I, E) onto the uninitialized memory starting with "Dest", - /// constructing elements as needed. - template - static void uninitialized_copy(It1 I, It1 E, It2 Dest) { - std::uninitialized_copy(I, E, Dest); - } - - /// Grow the allocated memory (without initializing new elements), doubling - /// the size of the allocated memory. Guarantees space for at least one more - /// element, or MinSize more elements if specified. - void grow(size_t MinSize = 0); - -public: - void push_back(const T &Elt) { - if (LLVM_UNLIKELY(this->EndX >= this->CapacityX)) - this->grow(); - ::new ((void*) this->end()) T(Elt); - this->setEnd(this->end()+1); - } - - void push_back(T &&Elt) { - if (LLVM_UNLIKELY(this->EndX >= this->CapacityX)) - this->grow(); - ::new ((void*) this->end()) T(::std::move(Elt)); - this->setEnd(this->end()+1); - } - - void pop_back() { - this->setEnd(this->end()-1); - this->end()->~T(); - } -}; - -// Define this out-of-line to dissuade the C++ compiler from inlining it. -template -void SmallVectorTemplateBase::grow(size_t MinSize) { - size_t CurCapacity = this->capacity(); - size_t CurSize = this->size(); - // Always grow, even from zero. - size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2)); - if (NewCapacity < MinSize) - NewCapacity = MinSize; - T *NewElts = static_cast(malloc(NewCapacity*sizeof(T))); - - // Move the elements over. - this->uninitialized_move(this->begin(), this->end(), NewElts); - - // Destroy the original elements. - destroy_range(this->begin(), this->end()); - - // If this wasn't grown from the inline copy, deallocate the old space. - if (!this->isSmall()) - free(this->begin()); - - this->setEnd(NewElts+CurSize); - this->BeginX = NewElts; - this->CapacityX = this->begin()+NewCapacity; -} - - -/// SmallVectorTemplateBase - This is where we put method -/// implementations that are designed to work with POD-like T's. -template -class SmallVectorTemplateBase : public SmallVectorTemplateCommon { -protected: - SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} - - // No need to do a destroy loop for POD's. - static void destroy_range(T *, T *) {} - - /// Move the range [I, E) onto the uninitialized memory - /// starting with "Dest", constructing elements into it as needed. - template - static void uninitialized_move(It1 I, It1 E, It2 Dest) { - // Just do a copy. - uninitialized_copy(I, E, Dest); - } - - /// Copy the range [I, E) onto the uninitialized memory - /// starting with "Dest", constructing elements into it as needed. - template - static void uninitialized_copy(It1 I, It1 E, It2 Dest) { - // Arbitrary iterator types; just use the basic implementation. - std::uninitialized_copy(I, E, Dest); - } - - /// Copy the range [I, E) onto the uninitialized memory - /// starting with "Dest", constructing elements into it as needed. - template - static void uninitialized_copy( - T1 *I, T1 *E, T2 *Dest, - typename std::enable_if::type, - T2>::value>::type * = nullptr) { - // Use memcpy for PODs iterated by pointers (which includes SmallVector - // iterators): std::uninitialized_copy optimizes to memmove, but we can - // use memcpy here. Note that I and E are iterators and thus might be - // invalid for memcpy if they are equal. - if (I != E) - memcpy(Dest, I, (E - I) * sizeof(T)); - } - - /// Double the size of the allocated memory, guaranteeing space for at - /// least one more element or MinSize if specified. - void grow(size_t MinSize = 0) { - this->grow_pod(MinSize*sizeof(T), sizeof(T)); - } -public: - void push_back(const T &Elt) { - if (LLVM_UNLIKELY(this->EndX >= this->CapacityX)) - this->grow(); - memcpy(this->end(), &Elt, sizeof(T)); - this->setEnd(this->end()+1); - } - - void pop_back() { - this->setEnd(this->end()-1); - } -}; - - -/// This class consists of common code factored out of the SmallVector class to -/// reduce code duplication based on the SmallVector 'N' template parameter. -template -class SmallVectorImpl : public SmallVectorTemplateBase::value> { - typedef SmallVectorTemplateBase::value > SuperClass; - - SmallVectorImpl(const SmallVectorImpl&) = delete; -public: - typedef typename SuperClass::iterator iterator; - typedef typename SuperClass::const_iterator const_iterator; - typedef typename SuperClass::size_type size_type; - -protected: - // Default ctor - Initialize to empty. - explicit SmallVectorImpl(unsigned N) - : SmallVectorTemplateBase::value>(N*sizeof(T)) { - } - -public: - ~SmallVectorImpl() { - // Destroy the constructed elements in the vector. - this->destroy_range(this->begin(), this->end()); - - // If this wasn't grown from the inline copy, deallocate the old space. - if (!this->isSmall()) - free(this->begin()); - } - - - void clear() { - this->destroy_range(this->begin(), this->end()); - this->EndX = this->BeginX; - } - - void resize(size_type N) { - if (N < this->size()) { - this->destroy_range(this->begin()+N, this->end()); - this->setEnd(this->begin()+N); - } else if (N > this->size()) { - if (this->capacity() < N) - this->grow(N); - for (auto I = this->end(), E = this->begin() + N; I != E; ++I) - new (&*I) T(); - this->setEnd(this->begin()+N); - } - } - - void resize(size_type N, const T &NV) { - if (N < this->size()) { - this->destroy_range(this->begin()+N, this->end()); - this->setEnd(this->begin()+N); - } else if (N > this->size()) { - if (this->capacity() < N) - this->grow(N); - std::uninitialized_fill(this->end(), this->begin()+N, NV); - this->setEnd(this->begin()+N); - } - } - - void reserve(size_type N) { - if (this->capacity() < N) - this->grow(N); - } - - T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() { - T Result = ::std::move(this->back()); - this->pop_back(); - return Result; - } - - void swap(SmallVectorImpl &RHS); - - /// Add the specified range to the end of the SmallVector. - template - void append(in_iter in_start, in_iter in_end) { - size_type NumInputs = std::distance(in_start, in_end); - // Grow allocated space if needed. - if (NumInputs > size_type(this->capacity_ptr()-this->end())) - this->grow(this->size()+NumInputs); - - // Copy the new elements over. - this->uninitialized_copy(in_start, in_end, this->end()); - this->setEnd(this->end() + NumInputs); - } - - /// Add the specified range to the end of the SmallVector. - void append(size_type NumInputs, const T &Elt) { - // Grow allocated space if needed. - if (NumInputs > size_type(this->capacity_ptr()-this->end())) - this->grow(this->size()+NumInputs); - - // Copy the new elements over. - std::uninitialized_fill_n(this->end(), NumInputs, Elt); - this->setEnd(this->end() + NumInputs); - } - - void append(std::initializer_list IL) { - append(IL.begin(), IL.end()); - } - - void assign(size_type NumElts, const T &Elt) { - clear(); - if (this->capacity() < NumElts) - this->grow(NumElts); - this->setEnd(this->begin()+NumElts); - std::uninitialized_fill(this->begin(), this->end(), Elt); - } - - void assign(std::initializer_list IL) { - clear(); - append(IL); - } - - iterator erase(const_iterator CI) { - // Just cast away constness because this is a non-const member function. - iterator I = const_cast(CI); - - assert(I >= this->begin() && "Iterator to erase is out of bounds."); - assert(I < this->end() && "Erasing at past-the-end iterator."); - - iterator N = I; - // Shift all elts down one. - std::move(I+1, this->end(), I); - // Drop the last elt. - this->pop_back(); - return(N); - } - - iterator erase(const_iterator CS, const_iterator CE) { - // Just cast away constness because this is a non-const member function. - iterator S = const_cast(CS); - iterator E = const_cast(CE); - - assert(S >= this->begin() && "Range to erase is out of bounds."); - assert(S <= E && "Trying to erase invalid range."); - assert(E <= this->end() && "Trying to erase past the end."); - - iterator N = S; - // Shift all elts down. - iterator I = std::move(E, this->end(), S); - // Drop the last elts. - this->destroy_range(I, this->end()); - this->setEnd(I); - return(N); - } - - iterator insert(iterator I, T &&Elt) { - if (I == this->end()) { // Important special case for empty vector. - this->push_back(::std::move(Elt)); - return this->end()-1; - } - - assert(I >= this->begin() && "Insertion iterator is out of bounds."); - assert(I <= this->end() && "Inserting past the end of the vector."); - - if (this->EndX >= this->CapacityX) { - size_t EltNo = I-this->begin(); - this->grow(); - I = this->begin()+EltNo; - } - - ::new ((void*) this->end()) T(::std::move(this->back())); - // Push everything else over. - std::move_backward(I, this->end()-1, this->end()); - this->setEnd(this->end()+1); - - // If we just moved the element we're inserting, be sure to update - // the reference. - T *EltPtr = &Elt; - if (I <= EltPtr && EltPtr < this->EndX) - ++EltPtr; - - *I = ::std::move(*EltPtr); - return I; - } - - iterator insert(iterator I, const T &Elt) { - if (I == this->end()) { // Important special case for empty vector. - this->push_back(Elt); - return this->end()-1; - } - - assert(I >= this->begin() && "Insertion iterator is out of bounds."); - assert(I <= this->end() && "Inserting past the end of the vector."); - - if (this->EndX >= this->CapacityX) { - size_t EltNo = I-this->begin(); - this->grow(); - I = this->begin()+EltNo; - } - ::new ((void*) this->end()) T(std::move(this->back())); - // Push everything else over. - std::move_backward(I, this->end()-1, this->end()); - this->setEnd(this->end()+1); - - // If we just moved the element we're inserting, be sure to update - // the reference. - const T *EltPtr = &Elt; - if (I <= EltPtr && EltPtr < this->EndX) - ++EltPtr; - - *I = *EltPtr; - return I; - } - - iterator insert(iterator I, size_type NumToInsert, const T &Elt) { - // Convert iterator to elt# to avoid invalidating iterator when we reserve() - size_t InsertElt = I - this->begin(); - - if (I == this->end()) { // Important special case for empty vector. - append(NumToInsert, Elt); - return this->begin()+InsertElt; - } - - assert(I >= this->begin() && "Insertion iterator is out of bounds."); - assert(I <= this->end() && "Inserting past the end of the vector."); - - // Ensure there is enough space. - reserve(this->size() + NumToInsert); - - // Uninvalidate the iterator. - I = this->begin()+InsertElt; - - // If there are more elements between the insertion point and the end of the - // range than there are being inserted, we can use a simple approach to - // insertion. Since we already reserved space, we know that this won't - // reallocate the vector. - if (size_t(this->end()-I) >= NumToInsert) { - T *OldEnd = this->end(); - append(std::move_iterator(this->end() - NumToInsert), - std::move_iterator(this->end())); - - // Copy the existing elements that get replaced. - std::move_backward(I, OldEnd-NumToInsert, OldEnd); - - std::fill_n(I, NumToInsert, Elt); - return I; - } - - // Otherwise, we're inserting more elements than exist already, and we're - // not inserting at the end. - - // Move over the elements that we're about to overwrite. - T *OldEnd = this->end(); - this->setEnd(this->end() + NumToInsert); - size_t NumOverwritten = OldEnd-I; - this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten); - - // Replace the overwritten part. - std::fill_n(I, NumOverwritten, Elt); - - // Insert the non-overwritten middle part. - std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt); - return I; - } - - template - iterator insert(iterator I, ItTy From, ItTy To) { - // Convert iterator to elt# to avoid invalidating iterator when we reserve() - size_t InsertElt = I - this->begin(); - - if (I == this->end()) { // Important special case for empty vector. - append(From, To); - return this->begin()+InsertElt; - } - - assert(I >= this->begin() && "Insertion iterator is out of bounds."); - assert(I <= this->end() && "Inserting past the end of the vector."); - - size_t NumToInsert = std::distance(From, To); - - // Ensure there is enough space. - reserve(this->size() + NumToInsert); - - // Uninvalidate the iterator. - I = this->begin()+InsertElt; - - // If there are more elements between the insertion point and the end of the - // range than there are being inserted, we can use a simple approach to - // insertion. Since we already reserved space, we know that this won't - // reallocate the vector. - if (size_t(this->end()-I) >= NumToInsert) { - T *OldEnd = this->end(); - append(std::move_iterator(this->end() - NumToInsert), - std::move_iterator(this->end())); - - // Copy the existing elements that get replaced. - std::move_backward(I, OldEnd-NumToInsert, OldEnd); - - std::copy(From, To, I); - return I; - } - - // Otherwise, we're inserting more elements than exist already, and we're - // not inserting at the end. - - // Move over the elements that we're about to overwrite. - T *OldEnd = this->end(); - this->setEnd(this->end() + NumToInsert); - size_t NumOverwritten = OldEnd-I; - this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten); - - // Replace the overwritten part. - for (T *J = I; NumOverwritten > 0; --NumOverwritten) { - *J = *From; - ++J; ++From; - } - - // Insert the non-overwritten middle part. - this->uninitialized_copy(From, To, OldEnd); - return I; - } - - void insert(iterator I, std::initializer_list IL) { - insert(I, IL.begin(), IL.end()); - } - - template void emplace_back(ArgTypes &&... Args) { - if (LLVM_UNLIKELY(this->EndX >= this->CapacityX)) - this->grow(); - ::new ((void *)this->end()) T(std::forward(Args)...); - this->setEnd(this->end() + 1); - } - - SmallVectorImpl &operator=(const SmallVectorImpl &RHS); - - SmallVectorImpl &operator=(SmallVectorImpl &&RHS); - - bool operator==(const SmallVectorImpl &RHS) const { - if (this->size() != RHS.size()) return false; - return std::equal(this->begin(), this->end(), RHS.begin()); - } - bool operator!=(const SmallVectorImpl &RHS) const { - return !(*this == RHS); - } - - bool operator<(const SmallVectorImpl &RHS) const { - return std::lexicographical_compare(this->begin(), this->end(), - RHS.begin(), RHS.end()); - } - - /// Set the array size to \p N, which the current array must have enough - /// capacity for. - /// - /// This does not construct or destroy any elements in the vector. - /// - /// Clients can use this in conjunction with capacity() to write past the end - /// of the buffer when they know that more elements are available, and only - /// update the size later. This avoids the cost of value initializing elements - /// which will only be overwritten. - void set_size(size_type N) { - assert(N <= this->capacity()); - this->setEnd(this->begin() + N); - } -}; - - -template -void SmallVectorImpl::swap(SmallVectorImpl &RHS) { - if (this == &RHS) return; - - // We can only avoid copying elements if neither vector is small. - if (!this->isSmall() && !RHS.isSmall()) { - std::swap(this->BeginX, RHS.BeginX); - std::swap(this->EndX, RHS.EndX); - std::swap(this->CapacityX, RHS.CapacityX); - return; - } - if (RHS.size() > this->capacity()) - this->grow(RHS.size()); - if (this->size() > RHS.capacity()) - RHS.grow(this->size()); - - // Swap the shared elements. - size_t NumShared = this->size(); - if (NumShared > RHS.size()) NumShared = RHS.size(); - for (size_type i = 0; i != NumShared; ++i) - std::swap((*this)[i], RHS[i]); - - // Copy over the extra elts. - if (this->size() > RHS.size()) { - size_t EltDiff = this->size() - RHS.size(); - this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end()); - RHS.setEnd(RHS.end()+EltDiff); - this->destroy_range(this->begin()+NumShared, this->end()); - this->setEnd(this->begin()+NumShared); - } else if (RHS.size() > this->size()) { - size_t EltDiff = RHS.size() - this->size(); - this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end()); - this->setEnd(this->end() + EltDiff); - this->destroy_range(RHS.begin()+NumShared, RHS.end()); - RHS.setEnd(RHS.begin()+NumShared); - } -} - -template -SmallVectorImpl &SmallVectorImpl:: - operator=(const SmallVectorImpl &RHS) { - // Avoid self-assignment. - if (this == &RHS) return *this; - - // If we already have sufficient space, assign the common elements, then - // destroy any excess. - size_t RHSSize = RHS.size(); - size_t CurSize = this->size(); - if (CurSize >= RHSSize) { - // Assign common elements. - iterator NewEnd; - if (RHSSize) - NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin()); - else - NewEnd = this->begin(); - - // Destroy excess elements. - this->destroy_range(NewEnd, this->end()); - - // Trim. - this->setEnd(NewEnd); - return *this; - } - - // If we have to grow to have enough elements, destroy the current elements. - // This allows us to avoid copying them during the grow. - // FIXME: don't do this if they're efficiently moveable. - if (this->capacity() < RHSSize) { - // Destroy current elements. - this->destroy_range(this->begin(), this->end()); - this->setEnd(this->begin()); - CurSize = 0; - this->grow(RHSSize); - } else if (CurSize) { - // Otherwise, use assignment for the already-constructed elements. - std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin()); - } - - // Copy construct the new elements in place. - this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(), - this->begin()+CurSize); - - // Set end. - this->setEnd(this->begin()+RHSSize); - return *this; -} - -template -SmallVectorImpl &SmallVectorImpl::operator=(SmallVectorImpl &&RHS) { - // Avoid self-assignment. - if (this == &RHS) return *this; - - // If the RHS isn't small, clear this vector and then steal its buffer. - if (!RHS.isSmall()) { - this->destroy_range(this->begin(), this->end()); - if (!this->isSmall()) free(this->begin()); - this->BeginX = RHS.BeginX; - this->EndX = RHS.EndX; - this->CapacityX = RHS.CapacityX; - RHS.resetToSmall(); - return *this; - } - - // If we already have sufficient space, assign the common elements, then - // destroy any excess. - size_t RHSSize = RHS.size(); - size_t CurSize = this->size(); - if (CurSize >= RHSSize) { - // Assign common elements. - iterator NewEnd = this->begin(); - if (RHSSize) - NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd); - - // Destroy excess elements and trim the bounds. - this->destroy_range(NewEnd, this->end()); - this->setEnd(NewEnd); - - // Clear the RHS. - RHS.clear(); - - return *this; - } - - // If we have to grow to have enough elements, destroy the current elements. - // This allows us to avoid copying them during the grow. - // FIXME: this may not actually make any sense if we can efficiently move - // elements. - if (this->capacity() < RHSSize) { - // Destroy current elements. - this->destroy_range(this->begin(), this->end()); - this->setEnd(this->begin()); - CurSize = 0; - this->grow(RHSSize); - } else if (CurSize) { - // Otherwise, use assignment for the already-constructed elements. - std::move(RHS.begin(), RHS.begin()+CurSize, this->begin()); - } - - // Move-construct the new elements in place. - this->uninitialized_move(RHS.begin()+CurSize, RHS.end(), - this->begin()+CurSize); - - // Set end. - this->setEnd(this->begin()+RHSSize); - - RHS.clear(); - return *this; -} - -/// Storage for the SmallVector elements which aren't contained in -/// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1' -/// element is in the base class. This is specialized for the N=1 and N=0 cases -/// to avoid allocating unnecessary storage. -template -struct SmallVectorStorage { - typename SmallVectorTemplateCommon::U InlineElts[N - 1]; -}; -template struct SmallVectorStorage {}; -template struct SmallVectorStorage {}; - -/// This is a 'vector' (really, a variable-sized array), optimized -/// for the case when the array is small. It contains some number of elements -/// in-place, which allows it to avoid heap allocation when the actual number of -/// elements is below that threshold. This allows normal "small" cases to be -/// fast without losing generality for large inputs. -/// -/// Note that this does not attempt to be exception safe. -/// -template -class SmallVector : public SmallVectorImpl { - /// Inline space for elements which aren't stored in the base class. - SmallVectorStorage Storage; -public: - SmallVector() : SmallVectorImpl(N) { - } - - explicit SmallVector(size_t Size, const T &Value = T()) - : SmallVectorImpl(N) { - this->assign(Size, Value); - } - - template - SmallVector(ItTy S, ItTy E) : SmallVectorImpl(N) { - this->append(S, E); - } - - template - explicit SmallVector(const llvm::iterator_range R) - : SmallVectorImpl(N) { - this->append(R.begin(), R.end()); - } - - SmallVector(std::initializer_list IL) : SmallVectorImpl(N) { - this->assign(IL); - } - - SmallVector(const SmallVector &RHS) : SmallVectorImpl(N) { - if (!RHS.empty()) - SmallVectorImpl::operator=(RHS); - } - - const SmallVector &operator=(const SmallVector &RHS) { - SmallVectorImpl::operator=(RHS); - return *this; - } - - SmallVector(SmallVector &&RHS) : SmallVectorImpl(N) { - if (!RHS.empty()) - SmallVectorImpl::operator=(::std::move(RHS)); - } - - const SmallVector &operator=(SmallVector &&RHS) { - SmallVectorImpl::operator=(::std::move(RHS)); - return *this; - } - - SmallVector(SmallVectorImpl &&RHS) : SmallVectorImpl(N) { - if (!RHS.empty()) - SmallVectorImpl::operator=(::std::move(RHS)); - } - - const SmallVector &operator=(SmallVectorImpl &&RHS) { - SmallVectorImpl::operator=(::std::move(RHS)); - return *this; - } - - const SmallVector &operator=(std::initializer_list IL) { - this->assign(IL); - return *this; - } -}; - -template -static inline size_t capacity_in_bytes(const SmallVector &X) { - return X.capacity_in_bytes(); -} - -} // End llvm namespace - -namespace std { - /// Implement std::swap in terms of SmallVector swap. - template - inline void - swap(llvm::SmallVectorImpl &LHS, llvm::SmallVectorImpl &RHS) { - LHS.swap(RHS); - } - - /// Implement std::swap in terms of SmallVector swap. - template - inline void - swap(llvm::SmallVector &LHS, llvm::SmallVector &RHS) { - LHS.swap(RHS); - } -} - -#endif diff --git a/wpiutil/include/llvm/StringExtras.h b/wpiutil/include/llvm/StringExtras.h deleted file mode 100644 index 9cf468a..0000000 --- a/wpiutil/include/llvm/StringExtras.h +++ /dev/null @@ -1,197 +0,0 @@ -//===-- llvm/ADT/StringExtras.h - Useful string functions -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains some functions that are useful when dealing with strings. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_STRINGEXTRAS_H -#define LLVM_ADT_STRINGEXTRAS_H - -#include "llvm/StringRef.h" -#include -#include - -namespace llvm { -template class SmallVectorImpl; - -/// hexdigit - Return the hexadecimal character for the -/// given number \p X (which should be less than 16). -static inline char hexdigit(unsigned X, bool LowerCase = false) { - const char HexChar = LowerCase ? 'a' : 'A'; - return X < 10 ? '0' + X : HexChar + X - 10; -} - -/// Construct a string ref from a boolean. -static inline StringRef toStringRef(bool B) { - return StringRef(B ? "true" : "false"); -} - -/// Interpret the given character \p C as a hexadecimal digit and return its -/// value. -/// -/// If \p C is not a valid hex digit, -1U is returned. -static inline unsigned hexDigitValue(char C) { - if (C >= '0' && C <= '9') return C-'0'; - if (C >= 'a' && C <= 'f') return C-'a'+10U; - if (C >= 'A' && C <= 'F') return C-'A'+10U; - return -1U; -} - -static inline std::string utohexstr(uint64_t X, bool LowerCase = false) { - char Buffer[17]; - char *BufPtr = std::end(Buffer); - - if (X == 0) *--BufPtr = '0'; - - while (X) { - unsigned char Mod = static_cast(X) & 15; - *--BufPtr = hexdigit(Mod, LowerCase); - X >>= 4; - } - - return std::string(BufPtr, std::end(Buffer)); -} - -/// Convert buffer \p Input to its hexadecimal representation. -/// The returned string is double the size of \p Input. -static inline std::string toHex(StringRef Input) { - static const char *const LUT = "0123456789ABCDEF"; - size_t Length = Input.size(); - - std::string Output; - Output.reserve(2 * Length); - for (size_t i = 0; i < Length; ++i) { - const unsigned char c = Input[i]; - Output.push_back(LUT[c >> 4]); - Output.push_back(LUT[c & 15]); - } - return Output; -} - -static inline std::string utostr(uint64_t X, bool isNeg = false) { - char Buffer[21]; - char *BufPtr = std::end(Buffer); - - if (X == 0) *--BufPtr = '0'; // Handle special case... - - while (X) { - *--BufPtr = '0' + char(X % 10); - X /= 10; - } - - if (isNeg) *--BufPtr = '-'; // Add negative sign... - return std::string(BufPtr, std::end(Buffer)); -} - - -static inline std::string itostr(int64_t X) { - if (X < 0) - return utostr(static_cast(-X), true); - else - return utostr(static_cast(X)); -} - -/// StrInStrNoCase - Portable version of strcasestr. Locates the first -/// occurrence of string 's1' in string 's2', ignoring case. Returns -/// the offset of s2 in s1 or npos if s2 cannot be found. -StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2); - -/// getToken - This function extracts one token from source, ignoring any -/// leading characters that appear in the Delimiters string, and ending the -/// token at any of the characters that appear in the Delimiters string. If -/// there are no tokens in the source string, an empty string is returned. -/// The function returns a pair containing the extracted token and the -/// remaining tail string. -std::pair getToken(StringRef Source, - StringRef Delimiters = " \t\n\v\f\r"); - -/// SplitString - Split up the specified string according to the specified -/// delimiters, appending the result fragments to the output list. -void SplitString(StringRef Source, - SmallVectorImpl &OutFragments, - StringRef Delimiters = " \t\n\v\f\r"); - -/// HashString - Hash function for strings. -/// -/// This is the Bernstein hash function. -// -// FIXME: Investigate whether a modified bernstein hash function performs -// better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx -// X*33+c -> X*33^c -static inline unsigned HashString(StringRef Str, unsigned Result = 0) { - for (StringRef::size_type i = 0, e = Str.size(); i != e; ++i) - Result = Result * 33 + (unsigned char)Str[i]; - return Result; -} - -/// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th). -static inline StringRef getOrdinalSuffix(unsigned Val) { - // It is critically important that we do this perfectly for - // user-written sequences with over 100 elements. - switch (Val % 100) { - case 11: - case 12: - case 13: - return "th"; - default: - switch (Val % 10) { - case 1: return "st"; - case 2: return "nd"; - case 3: return "rd"; - default: return "th"; - } - } -} - -template -inline std::string join_impl(IteratorT Begin, IteratorT End, - StringRef Separator, std::input_iterator_tag) { - std::string S; - if (Begin == End) - return S; - - S += (*Begin); - while (++Begin != End) { - S += Separator; - S += (*Begin); - } - return S; -} - -template -inline std::string join_impl(IteratorT Begin, IteratorT End, - StringRef Separator, std::forward_iterator_tag) { - std::string S; - if (Begin == End) - return S; - - size_t Len = (std::distance(Begin, End) - 1) * Separator.size(); - for (IteratorT I = Begin; I != End; ++I) - Len += (*Begin).size(); - S.reserve(Len); - S += (*Begin); - while (++Begin != End) { - S += Separator; - S += (*Begin); - } - return S; -} - -/// Joins the strings in the range [Begin, End), adding Separator between -/// the elements. -template -inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) { - typedef typename std::iterator_traits::iterator_category tag; - return join_impl(Begin, End, Separator, tag()); -} - -} // End llvm namespace - -#endif diff --git a/wpiutil/include/llvm/StringMap.h b/wpiutil/include/llvm/StringMap.h deleted file mode 100644 index 522c08a..0000000 --- a/wpiutil/include/llvm/StringMap.h +++ /dev/null @@ -1,476 +0,0 @@ -//===--- StringMap.h - String Hash table map interface ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the StringMap class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_STRINGMAP_H -#define LLVM_ADT_STRINGMAP_H - -#include "llvm/StringRef.h" -#include "llvm/PointerLikeTypeTraits.h" -#include -#include -#include - -namespace llvm { - template - class StringMapConstIterator; - template - class StringMapIterator; - template - class StringMapEntry; - -/// StringMapEntryBase - Shared base class of StringMapEntry instances. -class StringMapEntryBase { - unsigned StrLen; - -public: - explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {} - - unsigned getKeyLength() const { return StrLen; } -}; - -/// StringMapImpl - This is the base class of StringMap that is shared among -/// all of its instantiations. -class StringMapImpl { -protected: - // Array of NumBuckets pointers to entries, null pointers are holes. - // TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed - // by an array of the actual hash values as unsigned integers. - StringMapEntryBase **TheTable; - unsigned NumBuckets; - unsigned NumItems; - unsigned NumTombstones; - unsigned ItemSize; - -protected: - explicit StringMapImpl(unsigned itemSize) - : TheTable(nullptr), - // Initialize the map with zero buckets to allocation. - NumBuckets(0), NumItems(0), NumTombstones(0), ItemSize(itemSize) {} - StringMapImpl(StringMapImpl &&RHS) - : TheTable(RHS.TheTable), NumBuckets(RHS.NumBuckets), - NumItems(RHS.NumItems), NumTombstones(RHS.NumTombstones), - ItemSize(RHS.ItemSize) { - RHS.TheTable = nullptr; - RHS.NumBuckets = 0; - RHS.NumItems = 0; - RHS.NumTombstones = 0; - } - - StringMapImpl(unsigned InitSize, unsigned ItemSize); - unsigned RehashTable(unsigned BucketNo = 0); - - /// LookupBucketFor - Look up the bucket that the specified string should end - /// up in. If it already exists as a key in the map, the Item pointer for the - /// specified bucket will be non-null. Otherwise, it will be null. In either - /// case, the FullHashValue field of the bucket will be set to the hash value - /// of the string. - unsigned LookupBucketFor(StringRef Key); - - /// FindKey - Look up the bucket that contains the specified key. If it exists - /// in the map, return the bucket number of the key. Otherwise return -1. - /// This does not modify the map. - int FindKey(StringRef Key) const; - - /// RemoveKey - Remove the specified StringMapEntry from the table, but do not - /// delete it. This aborts if the value isn't in the table. - void RemoveKey(StringMapEntryBase *V); - - /// RemoveKey - Remove the StringMapEntry for the specified key from the - /// table, returning it. If the key is not in the table, this returns null. - StringMapEntryBase *RemoveKey(StringRef Key); - - /// Allocate the table with the specified number of buckets and otherwise - /// setup the map as empty. - void init(unsigned Size); - -public: - static StringMapEntryBase *getTombstoneVal() { - uintptr_t Val = static_cast(-1); - Val <<= PointerLikeTypeTraits::NumLowBitsAvailable; - return reinterpret_cast(Val); - } - - unsigned getNumBuckets() const { return NumBuckets; } - unsigned getNumItems() const { return NumItems; } - - bool empty() const { return NumItems == 0; } - unsigned size() const { return NumItems; } - - void swap(StringMapImpl &Other) { - std::swap(TheTable, Other.TheTable); - std::swap(NumBuckets, Other.NumBuckets); - std::swap(NumItems, Other.NumItems); - std::swap(NumTombstones, Other.NumTombstones); - } -}; - -/// StringMapEntry - This is used to represent one value that is inserted into -/// a StringMap. It contains the Value itself and the key: the string length -/// and data. -template -class StringMapEntry : public StringMapEntryBase { - StringMapEntry(StringMapEntry &E) = delete; - -public: - ValueTy second; - - explicit StringMapEntry(unsigned strLen) - : StringMapEntryBase(strLen), second() {} - template - StringMapEntry(unsigned strLen, InitTy &&... InitVals) - : StringMapEntryBase(strLen), second(std::forward(InitVals)...) {} - - StringRef getKey() const { - return StringRef(getKeyData(), getKeyLength()); - } - - const ValueTy &getValue() const { return second; } - ValueTy &getValue() { return second; } - - void setValue(const ValueTy &V) { second = V; } - - /// getKeyData - Return the start of the string data that is the key for this - /// value. The string data is always stored immediately after the - /// StringMapEntry object. - const char *getKeyData() const {return reinterpret_cast(this+1);} - - StringRef first() const { return StringRef(getKeyData(), getKeyLength()); } - - /// Create a StringMapEntry for the specified key construct the value using - /// \p InitiVals. - template - static StringMapEntry *Create(StringRef Key, InitTy &&... InitVals) { - unsigned KeyLength = Key.size(); - - // Allocate a new item with space for the string at the end and a null - // terminator. - unsigned AllocSize = static_cast(sizeof(StringMapEntry))+ - KeyLength+1; - - StringMapEntry *NewItem = - static_cast(std::malloc(AllocSize)); - - // Construct the value. - new (NewItem) StringMapEntry(KeyLength, std::forward(InitVals)...); - - // Copy the string information. - char *StrBuffer = const_cast(NewItem->getKeyData()); - if (KeyLength > 0) - memcpy(StrBuffer, Key.data(), KeyLength); - StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients. - return NewItem; - } - - static StringMapEntry *Create(StringRef Key) { - return Create(Key, ValueTy()); - } - - /// GetStringMapEntryFromKeyData - Given key data that is known to be embedded - /// into a StringMapEntry, return the StringMapEntry itself. - static StringMapEntry &GetStringMapEntryFromKeyData(const char *KeyData) { - char *Ptr = const_cast(KeyData) - sizeof(StringMapEntry); - return *reinterpret_cast(Ptr); - } - - /// Destroy - Destroy this StringMapEntry, releasing memory back to the - /// specified allocator. - void Destroy() { - // Free memory referenced by the item. - this->~StringMapEntry(); - std::free(static_cast(this)); - } -}; - - -/// StringMap - This is an unconventional map that is specialized for handling -/// keys that are "strings", which are basically ranges of bytes. This does some -/// funky memory allocation and hashing things to make it extremely efficient, -/// storing the string data *after* the value in the map. -template -class StringMap : public StringMapImpl { -public: - typedef StringMapEntry MapEntryTy; - - StringMap() : StringMapImpl(static_cast(sizeof(MapEntryTy))) {} - explicit StringMap(unsigned InitialSize) - : StringMapImpl(InitialSize, static_cast(sizeof(MapEntryTy))) {} - - StringMap(std::initializer_list> List) - : StringMapImpl(List.size(), static_cast(sizeof(MapEntryTy))) { - for (const auto &P : List) { - insert(P); - } - } - - StringMap(StringMap &&RHS) - : StringMapImpl(std::move(RHS)) {} - - StringMap &operator=(StringMap RHS) { - StringMapImpl::swap(RHS); - return *this; - } - - StringMap(const StringMap &RHS) : - StringMapImpl(static_cast(sizeof(MapEntryTy))) { - if (RHS.empty()) - return; - - // Allocate TheTable of the same size as RHS's TheTable, and set the - // sentinel appropriately (and NumBuckets). - init(RHS.NumBuckets); - unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1), - *RHSHashTable = (unsigned *)(RHS.TheTable + NumBuckets + 1); - - NumItems = RHS.NumItems; - NumTombstones = RHS.NumTombstones; - for (unsigned I = 0, E = NumBuckets; I != E; ++I) { - StringMapEntryBase *Bucket = RHS.TheTable[I]; - if (!Bucket || Bucket == getTombstoneVal()) { - TheTable[I] = Bucket; - continue; - } - - TheTable[I] = MapEntryTy::Create( - static_cast(Bucket)->getKey(), - static_cast(Bucket)->getValue()); - HashTable[I] = RHSHashTable[I]; - } - - // Note that here we've copied everything from the RHS into this object, - // tombstones included. We could, instead, have re-probed for each key to - // instantiate this new object without any tombstone buckets. The - // assumption here is that items are rarely deleted from most StringMaps, - // and so tombstones are rare, so the cost of re-probing for all inputs is - // not worthwhile. - } - - - typedef const char* key_type; - typedef ValueTy mapped_type; - typedef StringMapEntry value_type; - typedef size_t size_type; - - typedef StringMapConstIterator const_iterator; - typedef StringMapIterator iterator; - - iterator begin() { - return iterator(TheTable, NumBuckets == 0); - } - iterator end() { - return iterator(TheTable+NumBuckets, true); - } - const_iterator begin() const { - return const_iterator(TheTable, NumBuckets == 0); - } - const_iterator end() const { - return const_iterator(TheTable+NumBuckets, true); - } - - iterator find(StringRef Key) { - int Bucket = FindKey(Key); - if (Bucket == -1) return end(); - return iterator(TheTable+Bucket, true); - } - - const_iterator find(StringRef Key) const { - int Bucket = FindKey(Key); - if (Bucket == -1) return end(); - return const_iterator(TheTable+Bucket, true); - } - - /// lookup - Return the entry for the specified key, or a default - /// constructed value if no such entry exists. - ValueTy lookup(StringRef Key) const { - const_iterator it = find(Key); - if (it != end()) - return it->second; - return ValueTy(); - } - - /// Lookup the ValueTy for the \p Key, or create a default constructed value - /// if the key is not in the map. - ValueTy &operator[](StringRef Key) { - return emplace_second(Key).first->second; - } - - /// count - Return 1 if the element is in the map, 0 otherwise. - size_type count(StringRef Key) const { - return find(Key) == end() ? 0 : 1; - } - - /// insert - Insert the specified key/value pair into the map. If the key - /// already exists in the map, return false and ignore the request, otherwise - /// insert it and return true. - bool insert(MapEntryTy *KeyValue) { - unsigned BucketNo = LookupBucketFor(KeyValue->getKey()); - StringMapEntryBase *&Bucket = TheTable[BucketNo]; - if (Bucket && Bucket != getTombstoneVal()) - return false; // Already exists in map. - - if (Bucket == getTombstoneVal()) - --NumTombstones; - Bucket = KeyValue; - ++NumItems; - assert(NumItems + NumTombstones <= NumBuckets); - - RehashTable(); - return true; - } - - /// insert - Inserts the specified key/value pair into the map if the key - /// isn't already in the map. The bool component of the returned pair is true - /// if and only if the insertion takes place, and the iterator component of - /// the pair points to the element with key equivalent to the key of the pair. - std::pair insert(std::pair KV) { - return emplace_second(KV.first, std::move(KV.second)); - } - - /// Emplace a new element for the specified key into the map if the key isn't - /// already in the map. The bool component of the returned pair is true - /// if and only if the insertion takes place, and the iterator component of - /// the pair points to the element with key equivalent to the key of the pair. - template - std::pair emplace_second(StringRef Key, ArgsTy &&... Args) { - unsigned BucketNo = LookupBucketFor(Key); - StringMapEntryBase *&Bucket = TheTable[BucketNo]; - if (Bucket && Bucket != getTombstoneVal()) - return std::make_pair(iterator(TheTable + BucketNo, false), - false); // Already exists in map. - - if (Bucket == getTombstoneVal()) - --NumTombstones; - Bucket = MapEntryTy::Create(Key, std::forward(Args)...); - ++NumItems; - assert(NumItems + NumTombstones <= NumBuckets); - - BucketNo = RehashTable(BucketNo); - return std::make_pair(iterator(TheTable + BucketNo, false), true); - } - - // clear - Empties out the StringMap - void clear() { - if (empty()) return; - - // Zap all values, resetting the keys back to non-present (not tombstone), - // which is safe because we're removing all elements. - for (unsigned I = 0, E = NumBuckets; I != E; ++I) { - StringMapEntryBase *&Bucket = TheTable[I]; - if (Bucket && Bucket != getTombstoneVal()) { - static_cast(Bucket)->Destroy(); - } - Bucket = nullptr; - } - - NumItems = 0; - NumTombstones = 0; - } - - /// remove - Remove the specified key/value pair from the map, but do not - /// erase it. This aborts if the key is not in the map. - void remove(MapEntryTy *KeyValue) { - RemoveKey(KeyValue); - } - - void erase(iterator I) { - MapEntryTy &V = *I; - remove(&V); - V.Destroy(); - } - - bool erase(StringRef Key) { - iterator I = find(Key); - if (I == end()) return false; - erase(I); - return true; - } - - ~StringMap() { - // Delete all the elements in the map, but don't reset the elements - // to default values. This is a copy of clear(), but avoids unnecessary - // work not required in the destructor. - if (!empty()) { - for (unsigned I = 0, E = NumBuckets; I != E; ++I) { - StringMapEntryBase *Bucket = TheTable[I]; - if (Bucket && Bucket != getTombstoneVal()) { - static_cast(Bucket)->Destroy(); - } - } - } - free(TheTable); - } -}; - -template class StringMapConstIterator { -protected: - StringMapEntryBase **Ptr; - -public: - typedef StringMapEntry value_type; - - StringMapConstIterator() : Ptr(nullptr) { } - - explicit StringMapConstIterator(StringMapEntryBase **Bucket, - bool NoAdvance = false) - : Ptr(Bucket) { - if (!NoAdvance) AdvancePastEmptyBuckets(); - } - - const value_type &operator*() const { - return *static_cast*>(*Ptr); - } - const value_type *operator->() const { - return static_cast*>(*Ptr); - } - - bool operator==(const StringMapConstIterator &RHS) const { - return Ptr == RHS.Ptr; - } - bool operator!=(const StringMapConstIterator &RHS) const { - return Ptr != RHS.Ptr; - } - - inline StringMapConstIterator& operator++() { // Preincrement - ++Ptr; - AdvancePastEmptyBuckets(); - return *this; - } - StringMapConstIterator operator++(int) { // Postincrement - StringMapConstIterator tmp = *this; ++*this; return tmp; - } - -private: - void AdvancePastEmptyBuckets() { - while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal()) - ++Ptr; - } -}; - -template -class StringMapIterator : public StringMapConstIterator { -public: - StringMapIterator() {} - explicit StringMapIterator(StringMapEntryBase **Bucket, - bool NoAdvance = false) - : StringMapConstIterator(Bucket, NoAdvance) { - } - StringMapEntry &operator*() const { - return *static_cast*>(*this->Ptr); - } - StringMapEntry *operator->() const { - return static_cast*>(*this->Ptr); - } -}; - -} // namespace llvm - -#endif diff --git a/wpiutil/include/llvm/StringRef.h b/wpiutil/include/llvm/StringRef.h deleted file mode 100644 index c147534..0000000 --- a/wpiutil/include/llvm/StringRef.h +++ /dev/null @@ -1,623 +0,0 @@ -//===--- StringRef.h - Constant String Reference Wrapper --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_STRINGREF_H -#define LLVM_ADT_STRINGREF_H - -#include "llvm/iterator_range.h" -#include "llvm/Compiler.h" -#include -#include -#include -#include -#include -#include -#include - -namespace llvm { - template - class SmallVectorImpl; - class hash_code; - class StringRef; - - /// Helper functions for StringRef::getAsInteger. - bool getAsUnsignedInteger(StringRef Str, unsigned Radix, - unsigned long long &Result); - - bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result); - - /// StringRef - Represent a constant reference to a string, i.e. a character - /// array and a length, which need not be null terminated. - /// - /// This class does not own the string data, it is expected to be used in - /// situations where the character data resides in some other buffer, whose - /// lifetime extends past that of the StringRef. For this reason, it is not in - /// general safe to store a StringRef. - class StringRef { - public: - typedef const char *iterator; - typedef const char *const_iterator; - static const size_t npos = ~size_t(0); - typedef size_t size_type; - - private: - /// The start of the string, in an external buffer. - const char *Data; - - /// The length of the string. - /// MSB of length indicates if we are null terminated or not - /// Flag set is null terminated, flag not set is not - size_t Length; - - // Workaround memcmp issue with null pointers (undefined behavior) - // by providing a specialized version - static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) { - if (Length == 0) { return 0; } - return ::memcmp(Lhs,Rhs,Length); - } - - /// Set the flag to say we are null terminated - void set_null_terminated(bool set) { - if (set) - Length |= ((size_t)1 << (sizeof(size_t) * 8 - 1)); - else { - Length &= ~((size_t)1 << (sizeof(size_t) * 8 - 1)); - } - } - - public: - /// @name Constructors - /// @{ - - /// Construct an empty string ref. - /*implicit*/ StringRef() : Data(nullptr), Length(0) {} - - /// Construct a string ref from a cstring. - /*implicit*/ StringRef(const char *Str) - : Data(Str) { - assert(Str && "StringRef cannot be built from a NULL argument"); - Length = ::strlen(Str); // invoking strlen(NULL) is undefined behavior - // Require length to not use MSB of size - assert(Length < ~((size_t)1 << (sizeof(size_t) * 8 - 1))); - // If from a const char*, we are null terminated - set_null_terminated(true); - } - - /// Construct a string ref from a pointer and length. - /*implicit*/ StringRef(const char *data, size_t length) - : Data(data), Length(length) { - assert((data || length == 0) && - "StringRef cannot be built from a NULL argument with non-null length"); - // Require length to not use MSB of size - assert(Length < ~((size_t)1 << (sizeof(size_t) * 8 - 1))); - // If passed an explicit length, we are not null terminated - set_null_terminated(false); - } - - /// Construct a string ref from an std::string. - /*implicit*/ StringRef(const std::string &Str) - : Data(Str.data()), Length(Str.length()) { - // Require length to not use MSB of size - assert(Length < ~((size_t)1 << (sizeof(size_t) * 8 - 1))); - // If from a std::string, we are null terminated - set_null_terminated(true); - } - - /// @} - /// @name Iterators - /// @{ - - iterator begin() const { return Data; } - - iterator end() const { return Data + size(); } - - const unsigned char *bytes_begin() const { - return reinterpret_cast(begin()); - } - const unsigned char *bytes_end() const { - return reinterpret_cast(end()); - } - iterator_range bytes() const { - return make_range(bytes_begin(), bytes_end()); - } - - /// @} - /// @name String Operations - /// @{ - - /// data - Get a pointer to the start of the string (which may not be null - /// terminated). - const char *data() const { return Data; } - - /// c_str - Get a null terminated pointer to the start of the string - /// If string is not null terminated, use buffer to store new string - const char *c_str(llvm::SmallVectorImpl& buf) const; - - /// empty - Check if the string is empty. - bool empty() const { return size() == 0; } - - /// size - Get the string size. - size_t size() const { - return Length & ~((size_t)1 << (sizeof(size_t) * 8 - 1)); - } - - /// is_null_terminated - Get if the string is guaranteed null terminated - bool is_null_terminated() const { - return (Length & ((size_t)1 << (sizeof(size_t) * 8 - 1))) == - ((size_t)1 << (sizeof(size_t) * 8 - 1)); - } - - /// front - Get the first character in the string. - char front() const { - assert(!empty()); - return Data[0]; - } - - /// back - Get the last character in the string. - char back() const { - assert(!empty()); - return Data[size()-1]; - } - - // copy - Allocate copy in Allocator and return StringRef to it. - template StringRef copy(Allocator &A) const { - // Don't request a length 0 copy from the allocator. - if (empty()) - return StringRef(); - char *S = A.template Allocate(size()); - std::copy(begin(), end(), S); - return StringRef(S, size()); - } - - /// equals - Check for string equality, this is more efficient than - /// compare() when the relative ordering of inequal strings isn't needed. - bool equals(StringRef RHS) const { - return (size() == RHS.size() && - compareMemory(Data, RHS.Data, RHS.size()) == 0); - } - - /// equals_lower - Check for string equality, ignoring case. - bool equals_lower(StringRef RHS) const { - return size() == RHS.size() && compare_lower(RHS) == 0; - } - - /// compare - Compare two strings; the result is -1, 0, or 1 if this string - /// is lexicographically less than, equal to, or greater than the \p RHS. - int compare(StringRef RHS) const { - // Check the prefix for a mismatch. - if (int Res = compareMemory(Data, RHS.Data, std::min(size(), RHS.size()))) - return Res < 0 ? -1 : 1; - - // Otherwise the prefixes match, so we only need to check the lengths. - if (size() == RHS.size()) - return 0; - return size() < RHS.size() ? -1 : 1; - } - - /// compare_lower - Compare two strings, ignoring case. - int compare_lower(StringRef RHS) const; - - /// compare_numeric - Compare two strings, treating sequences of digits as - /// numbers. - int compare_numeric(StringRef RHS) const; - - /// str - Get the contents as an std::string. - std::string str() const { - if (!Data) return std::string(); - return std::string(Data, size()); - } - - /// @} - /// @name Operator Overloads - /// @{ - - char operator[](size_t Index) const { - assert(Index < size() && "Invalid index!"); - return Data[Index]; - } - - /// @} - /// @name Type Conversions - /// @{ - - operator std::string() const { - return str(); - } - - /// @} - /// @name String Predicates - /// @{ - - /// Check if this string starts with the given \p Prefix. - bool startswith(StringRef Prefix) const { - return size() >= Prefix.size() && - compareMemory(Data, Prefix.Data, Prefix.size()) == 0; - } - - /// Check if this string starts with the given \p Prefix, ignoring case. - bool startswith_lower(StringRef Prefix) const; - - /// Check if this string ends with the given \p Suffix. - bool endswith(StringRef Suffix) const { - return size() >= Suffix.size() && - compareMemory(end() - Suffix.size(), Suffix.Data, Suffix.size()) == 0; - } - - /// Check if this string ends with the given \p Suffix, ignoring case. - bool endswith_lower(StringRef Suffix) const; - - /// @} - /// @name String Searching - /// @{ - - /// Search for the first character \p C in the string. - /// - /// \returns The index of the first occurrence of \p C, or npos if not - /// found. - size_t find(char C, size_t From = 0) const { - size_t FindBegin = std::min(From, size()); - if (FindBegin < size()) { // Avoid calling memchr with nullptr. - // Just forward to memchr, which is faster than a hand-rolled loop. - if (const void *P = ::memchr(Data + FindBegin, C, size() - FindBegin)) - return static_cast(P) - Data; - } - return npos; - } - - /// Search for the first string \p Str in the string. - /// - /// \returns The index of the first occurrence of \p Str, or npos if not - /// found. - size_t find(StringRef Str, size_t From = 0) const; - - /// Search for the last character \p C in the string. - /// - /// \returns The index of the last occurrence of \p C, or npos if not - /// found. - size_t rfind(char C, size_t From = npos) const { - From = std::min(From, size()); - size_t i = From; - while (i != 0) { - --i; - if (Data[i] == C) - return i; - } - return npos; - } - - /// Search for the last string \p Str in the string. - /// - /// \returns The index of the last occurrence of \p Str, or npos if not - /// found. - size_t rfind(StringRef Str) const; - - /// Find the first character in the string that is \p C, or npos if not - /// found. Same as find. - size_t find_first_of(char C, size_t From = 0) const { - return find(C, From); - } - - /// Find the first character in the string that is in \p Chars, or npos if - /// not found. - /// - /// Complexity: O(size() + Chars.size()) - size_t find_first_of(StringRef Chars, size_t From = 0) const; - - /// Find the first character in the string that is not \p C or npos if not - /// found. - size_t find_first_not_of(char C, size_t From = 0) const; - - /// Find the first character in the string that is not in the string - /// \p Chars, or npos if not found. - /// - /// Complexity: O(size() + Chars.size()) - size_t find_first_not_of(StringRef Chars, size_t From = 0) const; - - /// Find the last character in the string that is \p C, or npos if not - /// found. - size_t find_last_of(char C, size_t From = npos) const { - return rfind(C, From); - } - - /// Find the last character in the string that is in \p C, or npos if not - /// found. - /// - /// Complexity: O(size() + Chars.size()) - size_t find_last_of(StringRef Chars, size_t From = npos) const; - - /// Find the last character in the string that is not \p C, or npos if not - /// found. - size_t find_last_not_of(char C, size_t From = npos) const; - - /// Find the last character in the string that is not in \p Chars, or - /// npos if not found. - /// - /// Complexity: O(size() + Chars.size()) - size_t find_last_not_of(StringRef Chars, size_t From = npos) const; - - /// @} - /// @name Helpful Algorithms - /// @{ - - /// Return the number of occurrences of \p C in the string. - size_t count(char C) const { - size_t Count = 0; - for (size_t i = 0, e = size(); i != e; ++i) - if (Data[i] == C) - ++Count; - return Count; - } - - /// Return the number of non-overlapped occurrences of \p Str in - /// the string. - size_t count(StringRef Str) const; - - /// Parse the current string as an integer of the specified radix. If - /// \p Radix is specified as zero, this does radix autosensing using - /// extended C rules: 0 is octal, 0x is hex, 0b is binary. - /// - /// If the string is invalid or if only a subset of the string is valid, - /// this returns true to signify the error. The string is considered - /// erroneous if empty or if it overflows T. - template - typename std::enable_if::is_signed, bool>::type - getAsInteger(unsigned Radix, T &Result) const { - long long LLVal; - if (getAsSignedInteger(*this, Radix, LLVal) || - static_cast(LLVal) != LLVal) - return true; - Result = LLVal; - return false; - } - - template - typename std::enable_if::is_signed, bool>::type - getAsInteger(unsigned Radix, T &Result) const { - unsigned long long ULLVal; - // The additional cast to unsigned long long is required to avoid the - // Visual C++ warning C4805: '!=' : unsafe mix of type 'bool' and type - // 'unsigned __int64' when instantiating getAsInteger with T = bool. - if (getAsUnsignedInteger(*this, Radix, ULLVal) || - static_cast(static_cast(ULLVal)) != ULLVal) - return true; - Result = ULLVal; - return false; - } - - /// @} - /// @name String Operations - /// @{ - - // Convert the given ASCII string to lowercase. - std::string lower() const; - - /// Convert the given ASCII string to uppercase. - std::string upper() const; - - /// @} - /// @name Substring Operations - /// @{ - - /// Return a reference to the substring from [Start, Start + N). - /// - /// \param Start The index of the starting character in the substring; if - /// the index is npos or greater than the length of the string then the - /// empty substring will be returned. - /// - /// \param N The number of characters to included in the substring. If N - /// exceeds the number of characters remaining in the string, the string - /// suffix (starting with \p Start) will be returned. - StringRef substr(size_t Start, size_t N = npos) const { - Start = std::min(Start, size()); - return StringRef(Data + Start, std::min(N, size() - Start)); - } - - /// Return a StringRef equal to 'this' but with the first \p N elements - /// dropped. - StringRef drop_front(size_t N = 1) const { - assert(size() >= N && "Dropping more elements than exist"); - return substr(N); - } - - /// Return a StringRef equal to 'this' but with the last \p N elements - /// dropped. - StringRef drop_back(size_t N = 1) const { - assert(size() >= N && "Dropping more elements than exist"); - return substr(0, size()-N); - } - - /// Return a reference to the substring from [Start, End). - /// - /// \param Start The index of the starting character in the substring; if - /// the index is npos or greater than the length of the string then the - /// empty substring will be returned. - /// - /// \param End The index following the last character to include in the - /// substring. If this is npos or exceeds the number of characters - /// remaining in the string, the string suffix (starting with \p Start) - /// will be returned. If this is less than \p Start, an empty string will - /// be returned. - StringRef slice(size_t Start, size_t End) const { - Start = std::min(Start, size()); - End = std::min(std::max(Start, End), size()); - return StringRef(Data + Start, End - Start); - } - - /// Split into two substrings around the first occurrence of a separator - /// character. - /// - /// If \p Separator is in the string, then the result is a pair (LHS, RHS) - /// such that (*this == LHS + Separator + RHS) is true and RHS is - /// maximal. If \p Separator is not in the string, then the result is a - /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). - /// - /// \param Separator The character to split on. - /// \returns The split substrings. - std::pair split(char Separator) const { - size_t Idx = find(Separator); - if (Idx == npos) - return std::make_pair(*this, StringRef()); - return std::make_pair(slice(0, Idx), slice(Idx+1, npos)); - } - - /// Split into two substrings around the first occurrence of a separator - /// string. - /// - /// If \p Separator is in the string, then the result is a pair (LHS, RHS) - /// such that (*this == LHS + Separator + RHS) is true and RHS is - /// maximal. If \p Separator is not in the string, then the result is a - /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). - /// - /// \param Separator - The string to split on. - /// \return - The split substrings. - std::pair split(StringRef Separator) const { - size_t Idx = find(Separator); - if (Idx == npos) - return std::make_pair(*this, StringRef()); - return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos)); - } - - /// Split into substrings around the occurrences of a separator string. - /// - /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most - /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1 - /// elements are added to A. - /// If \p KeepEmpty is false, empty strings are not added to \p A. They - /// still count when considering \p MaxSplit - /// An useful invariant is that - /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true - /// - /// \param A - Where to put the substrings. - /// \param Separator - The string to split on. - /// \param MaxSplit - The maximum number of times the string is split. - /// \param KeepEmpty - True if empty substring should be added. - void split(SmallVectorImpl &A, - StringRef Separator, int MaxSplit = -1, - bool KeepEmpty = true) const; - - /// Split into substrings around the occurrences of a separator character. - /// - /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most - /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1 - /// elements are added to A. - /// If \p KeepEmpty is false, empty strings are not added to \p A. They - /// still count when considering \p MaxSplit - /// An useful invariant is that - /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true - /// - /// \param A - Where to put the substrings. - /// \param Separator - The string to split on. - /// \param MaxSplit - The maximum number of times the string is split. - /// \param KeepEmpty - True if empty substring should be added. - void split(SmallVectorImpl &A, char Separator, int MaxSplit = -1, - bool KeepEmpty = true) const; - - /// Split into two substrings around the last occurrence of a separator - /// character. - /// - /// If \p Separator is in the string, then the result is a pair (LHS, RHS) - /// such that (*this == LHS + Separator + RHS) is true and RHS is - /// minimal. If \p Separator is not in the string, then the result is a - /// pair (LHS, RHS) where (*this == LHS) and (RHS == ""). - /// - /// \param Separator - The character to split on. - /// \return - The split substrings. - std::pair rsplit(char Separator) const { - size_t Idx = rfind(Separator); - if (Idx == npos) - return std::make_pair(*this, StringRef()); - return std::make_pair(slice(0, Idx), slice(Idx+1, npos)); - } - - /// Return string with consecutive \p Char characters starting from the - /// the left removed. - StringRef ltrim(char Char) const { - return drop_front(std::min(size(), find_first_not_of(Char))); - } - - /// Return string with consecutive characters in \p Chars starting from - /// the left removed. - StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const { - return drop_front(std::min(size(), find_first_not_of(Chars))); - } - - /// Return string with consecutive \p Char characters starting from the - /// right removed. - StringRef rtrim(char Char) const { - return drop_back(size() - std::min(size(), find_last_not_of(Char) + 1)); - } - - /// Return string with consecutive characters in \p Chars starting from - /// the right removed. - StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const { - return drop_back(size() - std::min(size(), find_last_not_of(Chars) + 1)); - } - - /// Return string with consecutive \p Char characters starting from the - /// left and right removed. - StringRef trim(char Char) const { - return ltrim(Char).rtrim(Char); - } - - /// Return string with consecutive characters in \p Chars starting from - /// the left and right removed. - StringRef trim(StringRef Chars = " \t\n\v\f\r") const { - return ltrim(Chars).rtrim(Chars); - } - - /// @} - }; - - /// @name StringRef Comparison Operators - /// @{ - - inline bool operator==(StringRef LHS, StringRef RHS) { - return LHS.equals(RHS); - } - - inline bool operator!=(StringRef LHS, StringRef RHS) { - return !(LHS == RHS); - } - - inline bool operator<(StringRef LHS, StringRef RHS) { - return LHS.compare(RHS) == -1; - } - - inline bool operator<=(StringRef LHS, StringRef RHS) { - return LHS.compare(RHS) != 1; - } - - inline bool operator>(StringRef LHS, StringRef RHS) { - return LHS.compare(RHS) == 1; - } - - inline bool operator>=(StringRef LHS, StringRef RHS) { - return LHS.compare(RHS) != -1; - } - - inline std::string &operator+=(std::string &buffer, StringRef string) { - return buffer.append(string.data(), string.size()); - } - - inline std::ostream &operator<<(std::ostream &os, StringRef string) { - os.write(string.data(), string.size()); - return os; - } - - /// @} - - /// \brief Compute a hash_code for a StringRef. - hash_code hash_value(StringRef S); - - // StringRefs can be treated like a POD type. - template struct isPodLike; - template <> struct isPodLike { static const bool value = true; }; -} // namespace llvm - -#endif diff --git a/wpiutil/include/llvm/WindowsError.h b/wpiutil/include/llvm/WindowsError.h deleted file mode 100644 index 63bfe59..0000000 --- a/wpiutil/include/llvm/WindowsError.h +++ /dev/null @@ -1,19 +0,0 @@ -//===-- WindowsError.h - Support for mapping windows errors to posix-------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_WINDOWSERROR_H -#define LLVM_SUPPORT_WINDOWSERROR_H - -#include - -namespace llvm { -std::error_code mapWindowsError(unsigned EV); -} - -#endif diff --git a/wpiutil/include/llvm/iterator_range.h b/wpiutil/include/llvm/iterator_range.h deleted file mode 100644 index 3dd679b..0000000 --- a/wpiutil/include/llvm/iterator_range.h +++ /dev/null @@ -1,68 +0,0 @@ -//===- iterator_range.h - A range adaptor for iterators ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// \file -/// This provides a very simple, boring adaptor for a begin and end iterator -/// into a range type. This should be used to build range views that work well -/// with range based for loops and range based constructors. -/// -/// Note that code here follows more standards-based coding conventions as it -/// is mirroring proposed interfaces for standardization. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_ITERATOR_RANGE_H -#define LLVM_ADT_ITERATOR_RANGE_H - -#include -#include - -namespace llvm { - -/// \brief A range adaptor for a pair of iterators. -/// -/// This just wraps two iterators into a range-compatible interface. Nothing -/// fancy at all. -template -class iterator_range { - IteratorT begin_iterator, end_iterator; - -public: - //TODO: Add SFINAE to test that the Container's iterators match the range's - // iterators. - template - iterator_range(Container &&c) - //TODO: Consider ADL/non-member begin/end calls. - : begin_iterator(c.begin()), end_iterator(c.end()) {} - iterator_range(IteratorT begin_iterator, IteratorT end_iterator) - : begin_iterator(std::move(begin_iterator)), - end_iterator(std::move(end_iterator)) {} - - IteratorT begin() const { return begin_iterator; } - IteratorT end() const { return end_iterator; } -}; - -/// \brief Convenience function for iterating over sub-ranges. -/// -/// This provides a bit of syntactic sugar to make using sub-ranges -/// in for loops a bit easier. Analogous to std::make_pair(). -template iterator_range make_range(T x, T y) { - return iterator_range(std::move(x), std::move(y)); -} - -template iterator_range make_range(std::pair p) { - return iterator_range(std::move(p.first), std::move(p.second)); -} - -template -iterator_range()))> drop_begin(T &&t, int n) { - return make_range(std::next(begin(t), n), end(t)); -} -} - -#endif diff --git a/wpiutil/include/llvm/raw_os_ostream.h b/wpiutil/include/llvm/raw_os_ostream.h deleted file mode 100644 index 22dfa59..0000000 --- a/wpiutil/include/llvm/raw_os_ostream.h +++ /dev/null @@ -1,42 +0,0 @@ -//===- raw_os_ostream.h - std::ostream adaptor for raw_ostream --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the raw_os_ostream class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_RAW_OS_OSTREAM_H -#define LLVM_SUPPORT_RAW_OS_OSTREAM_H - -#include "llvm/raw_ostream.h" -#include - -namespace llvm { - -/// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a -/// simple adaptor class. It does not check for output errors; clients should -/// use the underlying stream to detect errors. -class raw_os_ostream : public raw_ostream { - std::ostream &OS; - - /// write_impl - See raw_ostream::write_impl. - void write_impl(const char *Ptr, size_t Size) override; - - /// current_pos - Return the current position within the stream, not - /// counting the bytes currently in the buffer. - uint64_t current_pos() const override; - -public: - raw_os_ostream(std::ostream &O) : OS(O) {} - ~raw_os_ostream() override; -}; - -} // end llvm namespace - -#endif diff --git a/wpiutil/include/llvm/raw_ostream.h b/wpiutil/include/llvm/raw_ostream.h deleted file mode 100644 index aa2d98d..0000000 --- a/wpiutil/include/llvm/raw_ostream.h +++ /dev/null @@ -1,547 +0,0 @@ -//===--- raw_ostream.h - Raw output stream ----------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the raw_ostream class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_RAW_OSTREAM_H -#define LLVM_SUPPORT_RAW_OSTREAM_H - -#include "llvm/SmallVector.h" -#include "llvm/StringRef.h" -#include -#include - -namespace llvm { -class format_object_base; -class FormattedString; -class FormattedNumber; -template class SmallVectorImpl; - -namespace sys { -namespace fs { -enum OpenFlags : unsigned { - F_None = 0, - - /// F_Excl - When opening a file, this flag makes raw_fd_ostream - /// report an error if the file already exists. - F_Excl = 1, - - /// F_Append - When opening a file, if it already exists append to the - /// existing file instead of returning an error. This may not be specified - /// with F_Excl. - F_Append = 2, - - /// The file should be opened in text mode on platforms that make this - /// distinction. - F_Text = 4, - - /// Open the file for read and write. - F_RW = 8 -}; - -inline OpenFlags operator|(OpenFlags A, OpenFlags B) { - return OpenFlags(unsigned(A) | unsigned(B)); -} - -inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) { - A = A | B; - return A; -} -} // namespace fs -} // namespace sys - -/// This class implements an extremely fast bulk output stream that can *only* -/// output to a stream. It does not support seeking, reopening, rewinding, line -/// buffered disciplines etc. It is a simple buffer that outputs -/// a chunk at a time. -class raw_ostream { -private: - void operator=(const raw_ostream &) = delete; - raw_ostream(const raw_ostream &) = delete; - - /// The buffer is handled in such a way that the buffer is - /// uninitialized, unbuffered, or out of space when OutBufCur >= - /// OutBufEnd. Thus a single comparison suffices to determine if we - /// need to take the slow path to write a single character. - /// - /// The buffer is in one of three states: - /// 1. Unbuffered (BufferMode == Unbuffered) - /// 1. Uninitialized (BufferMode != Unbuffered && OutBufStart == 0). - /// 2. Buffered (BufferMode != Unbuffered && OutBufStart != 0 && - /// OutBufEnd - OutBufStart >= 1). - /// - /// If buffered, then the raw_ostream owns the buffer if (BufferMode == - /// InternalBuffer); otherwise the buffer has been set via SetBuffer and is - /// managed by the subclass. - /// - /// If a subclass installs an external buffer using SetBuffer then it can wait - /// for a \see write_impl() call to handle the data which has been put into - /// this buffer. - char *OutBufStart, *OutBufEnd, *OutBufCur; - - enum BufferKind { - Unbuffered = 0, - InternalBuffer, - ExternalBuffer - } BufferMode; - -public: - // color order matches ANSI escape sequence, don't change - enum Colors { - BLACK=0, - RED, - GREEN, - YELLOW, - BLUE, - MAGENTA, - CYAN, - WHITE, - SAVEDCOLOR - }; - - explicit raw_ostream(bool unbuffered = false) - : BufferMode(unbuffered ? Unbuffered : InternalBuffer) { - // Start out ready to flush. - OutBufStart = OutBufEnd = OutBufCur = nullptr; - } - - virtual ~raw_ostream(); - - /// tell - Return the current offset with the file. - uint64_t tell() const { return current_pos() + GetNumBytesInBuffer(); } - - //===--------------------------------------------------------------------===// - // Configuration Interface - //===--------------------------------------------------------------------===// - - /// Set the stream to be buffered, with an automatically determined buffer - /// size. - void SetBuffered(); - - /// Set the stream to be buffered, using the specified buffer size. - void SetBufferSize(size_t Size) { - flush(); - SetBufferAndMode(new char[Size], Size, InternalBuffer); - } - - size_t GetBufferSize() const { - // If we're supposed to be buffered but haven't actually gotten around - // to allocating the buffer yet, return the value that would be used. - if (BufferMode != Unbuffered && OutBufStart == nullptr) - return preferred_buffer_size(); - - // Otherwise just return the size of the allocated buffer. - return OutBufEnd - OutBufStart; - } - - /// Set the stream to be unbuffered. When unbuffered, the stream will flush - /// after every write. This routine will also flush the buffer immediately - /// when the stream is being set to unbuffered. - void SetUnbuffered() { - flush(); - SetBufferAndMode(nullptr, 0, Unbuffered); - } - - size_t GetNumBytesInBuffer() const { - return OutBufCur - OutBufStart; - } - - //===--------------------------------------------------------------------===// - // Data Output Interface - //===--------------------------------------------------------------------===// - - void flush() { - if (OutBufCur != OutBufStart) - flush_nonempty(); - } - - raw_ostream &operator<<(char C) { - if (OutBufCur >= OutBufEnd) - return write(C); - *OutBufCur++ = C; - return *this; - } - - raw_ostream &operator<<(unsigned char C) { - if (OutBufCur >= OutBufEnd) - return write(C); - *OutBufCur++ = C; - return *this; - } - - raw_ostream &operator<<(signed char C) { - if (OutBufCur >= OutBufEnd) - return write(C); - *OutBufCur++ = C; - return *this; - } - - raw_ostream &operator<<(StringRef Str) { - // Inline fast path, particularly for strings with a known length. - size_t Size = Str.size(); - - // Make sure we can use the fast path. - if (Size > (size_t)(OutBufEnd - OutBufCur)) - return write(Str.data(), Size); - - if (Size) { - memcpy(OutBufCur, Str.data(), Size); - OutBufCur += Size; - } - return *this; - } - - raw_ostream &operator<<(const char *Str) { - // Inline fast path, particularly for constant strings where a sufficiently - // smart compiler will simplify strlen. - - return this->operator<<(StringRef(Str)); - } - - raw_ostream &operator<<(const std::string &Str) { - // Avoid the fast path, it would only increase code size for a marginal win. - return write(Str.data(), Str.length()); - } - - raw_ostream &operator<<(const llvm::SmallVectorImpl &Str) { - return write(Str.data(), Str.size()); - } - - raw_ostream &operator<<(unsigned long N); - raw_ostream &operator<<(long N); - raw_ostream &operator<<(unsigned long long N); - raw_ostream &operator<<(long long N); - raw_ostream &operator<<(const void *P); - raw_ostream &operator<<(unsigned int N) { - return this->operator<<(static_cast(N)); - } - - raw_ostream &operator<<(int N) { - return this->operator<<(static_cast(N)); - } - - raw_ostream &operator<<(double N); - - /// Output \p N in hexadecimal, without any prefix or padding. - raw_ostream &write_hex(unsigned long long N); - - /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't - /// satisfy std::isprint into an escape sequence. - raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false); - - raw_ostream &write(unsigned char C); - raw_ostream &write(const char *Ptr, size_t Size); - - // Formatted output, see the format() function in Support/Format.h. - raw_ostream &operator<<(const format_object_base &Fmt); - - // Formatted output, see the leftJustify() function in Support/Format.h. - raw_ostream &operator<<(const FormattedString &); - - // Formatted output, see the formatHex() function in Support/Format.h. - raw_ostream &operator<<(const FormattedNumber &); - - /// indent - Insert 'NumSpaces' spaces. - raw_ostream &indent(unsigned NumSpaces); - - /// Changes the foreground color of text that will be output from this point - /// forward. - /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to - /// change only the bold attribute, and keep colors untouched - /// @param Bold bold/brighter text, default false - /// @param BG if true change the background, default: change foreground - /// @returns itself so it can be used within << invocations - virtual raw_ostream &changeColor(enum Colors Color, - bool Bold = false, - bool BG = false) { - (void)Color; - (void)Bold; - (void)BG; - return *this; - } - - /// Resets the colors to terminal defaults. Call this when you are done - /// outputting colored text, or before program exit. - virtual raw_ostream &resetColor() { return *this; } - - /// Reverses the foreground and background colors. - virtual raw_ostream &reverseColor() { return *this; } - - /// This function determines if this stream is connected to a "tty" or - /// "console" window. That is, the output would be displayed to the user - /// rather than being put on a pipe or stored in a file. - virtual bool is_displayed() const { return false; } - - /// This function determines if this stream is displayed and supports colors. - virtual bool has_colors() const { return is_displayed(); } - - //===--------------------------------------------------------------------===// - // Subclass Interface - //===--------------------------------------------------------------------===// - -private: - /// The is the piece of the class that is implemented by subclasses. This - /// writes the \p Size bytes starting at - /// \p Ptr to the underlying stream. - /// - /// This function is guaranteed to only be called at a point at which it is - /// safe for the subclass to install a new buffer via SetBuffer. - /// - /// \param Ptr The start of the data to be written. For buffered streams this - /// is guaranteed to be the start of the buffer. - /// - /// \param Size The number of bytes to be written. - /// - /// \invariant { Size > 0 } - virtual void write_impl(const char *Ptr, size_t Size) = 0; - - // An out of line virtual method to provide a home for the class vtable. - virtual void handle(); - - /// Return the current position within the stream, not counting the bytes - /// currently in the buffer. - virtual uint64_t current_pos() const = 0; - -protected: - /// Use the provided buffer as the raw_ostream buffer. This is intended for - /// use only by subclasses which can arrange for the output to go directly - /// into the desired output buffer, instead of being copied on each flush. - void SetBuffer(char *BufferStart, size_t Size) { - SetBufferAndMode(BufferStart, Size, ExternalBuffer); - } - - /// Return an efficient buffer size for the underlying output mechanism. - virtual size_t preferred_buffer_size() const; - - /// Return the beginning of the current stream buffer, or 0 if the stream is - /// unbuffered. - const char *getBufferStart() const { return OutBufStart; } - - //===--------------------------------------------------------------------===// - // Private Interface - //===--------------------------------------------------------------------===// -private: - /// Install the given buffer and mode. - void SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode); - - /// Flush the current buffer, which is known to be non-empty. This outputs the - /// currently buffered data and resets the buffer to empty. - void flush_nonempty(); - - /// Copy data into the buffer. Size must not be greater than the number of - /// unused bytes in the buffer. - void copy_to_buffer(const char *Ptr, size_t Size); -}; - -/// An abstract base class for streams implementations that also support a -/// pwrite operation. This is useful for code that can mostly stream out data, -/// but needs to patch in a header that needs to know the output size. -class raw_pwrite_stream : public raw_ostream { - virtual void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) = 0; - -public: - explicit raw_pwrite_stream(bool Unbuffered = false) - : raw_ostream(Unbuffered) {} - void pwrite(const char *Ptr, size_t Size, uint64_t Offset) { -#ifndef NDBEBUG - uint64_t Pos = tell(); - // /dev/null always reports a pos of 0, so we cannot perform this check - // in that case. - if (Pos) - assert(Size + Offset <= Pos && "We don't support extending the stream"); -#endif - pwrite_impl(Ptr, Size, Offset); - } -}; - -//===----------------------------------------------------------------------===// -// File Output Streams -//===----------------------------------------------------------------------===// - -/// A raw_ostream that writes to a file descriptor. -/// -class raw_fd_ostream : public raw_pwrite_stream { - int FD; - bool ShouldClose; - - /// Error This flag is true if an error of any kind has been detected. - /// - bool Error; - - uint64_t pos; - - bool SupportsSeeking; - - /// See raw_ostream::write_impl. - void write_impl(const char *Ptr, size_t Size) override; - - void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override; - - /// Return the current position within the stream, not counting the bytes - /// currently in the buffer. - uint64_t current_pos() const override { return pos; } - - /// Determine an efficient buffer size. - size_t preferred_buffer_size() const override; - - /// Set the flag indicating that an output error has been encountered. - void error_detected() { Error = true; } - -public: - /// Open the specified file for writing. If an error occurs, information - /// about the error is put into EC, and the stream should be immediately - /// destroyed; - /// \p Flags allows optional flags to control how the file will be opened. - /// - /// As a special case, if Filename is "-", then the stream will use - /// STDOUT_FILENO instead of opening a file. Note that it will still consider - /// itself to own the file descriptor. In particular, it will close the - /// file descriptor when it is done (this is necessary to detect - /// output errors). - raw_fd_ostream(StringRef Filename, std::error_code &EC, - sys::fs::OpenFlags Flags); - - /// FD is the file descriptor that this writes to. If ShouldClose is true, - /// this closes the file when the stream is destroyed. - raw_fd_ostream(int fd, bool shouldClose, bool unbuffered=false); - - ~raw_fd_ostream() override; - - /// Manually flush the stream and close the file. Note that this does not call - /// fsync. - void close(); - - bool supportsSeeking() { return SupportsSeeking; } - - /// Flushes the stream and repositions the underlying file descriptor position - /// to the offset specified from the beginning of the file. - uint64_t seek(uint64_t off); - - /// Return the value of the flag in this raw_fd_ostream indicating whether an - /// output error has been encountered. - /// This doesn't implicitly flush any pending output. Also, it doesn't - /// guarantee to detect all errors unless the stream has been closed. - bool has_error() const { - return Error; - } - - /// Set the flag read by has_error() to false. If the error flag is set at the - /// time when this raw_ostream's destructor is called, report_fatal_error is - /// called to report the error. Use clear_error() after handling the error to - /// avoid this behavior. - /// - /// "Errors should never pass silently. - /// Unless explicitly silenced." - /// - from The Zen of Python, by Tim Peters - /// - void clear_error() { - Error = false; - } -}; - -/// This returns a reference to a raw_ostream for standard output. Use it like: -/// outs() << "foo" << "bar"; -raw_ostream &outs(); - -/// This returns a reference to a raw_ostream for standard error. Use it like: -/// errs() << "foo" << "bar"; -raw_ostream &errs(); - -/// This returns a reference to a raw_ostream which simply discards output. -raw_ostream &nulls(); - -//===----------------------------------------------------------------------===// -// Output Stream Adaptors -//===----------------------------------------------------------------------===// - -/// A raw_ostream that writes to an std::string. This is a simple adaptor -/// class. This class does not encounter output errors. -class raw_string_ostream : public raw_ostream { - std::string &OS; - - /// See raw_ostream::write_impl. - void write_impl(const char *Ptr, size_t Size) override; - - /// Return the current position within the stream, not counting the bytes - /// currently in the buffer. - uint64_t current_pos() const override { return OS.size(); } - -public: - explicit raw_string_ostream(std::string &O) : OS(O) {} - ~raw_string_ostream() override; - - /// Flushes the stream contents to the target string and returns the string's - /// reference. - std::string& str() { - flush(); - return OS; - } -}; - -/// A raw_ostream that writes to an SmallVector or SmallString. This is a -/// simple adaptor class. This class does not encounter output errors. -/// raw_svector_ostream operates without a buffer, delegating all memory -/// management to the SmallString. Thus the SmallString is always up-to-date, -/// may be used directly and there is no need to call flush(). -class raw_svector_ostream : public raw_pwrite_stream { - SmallVectorImpl &OS; - - /// See raw_ostream::write_impl. - void write_impl(const char *Ptr, size_t Size) override; - - void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override; - - /// Return the current position within the stream. - uint64_t current_pos() const override; - -public: - /// Construct a new raw_svector_ostream. - /// - /// \param O The vector to write to; this should generally have at least 128 - /// bytes free to avoid any extraneous memory overhead. - explicit raw_svector_ostream(SmallVectorImpl &O) : OS(O) { - SetUnbuffered(); - } - ~raw_svector_ostream() override {} - - void flush() = delete; - - /// Return a StringRef for the vector contents. - StringRef str() { return StringRef(OS.data(), OS.size()); } -}; - -/// A raw_ostream that discards all output. -class raw_null_ostream : public raw_pwrite_stream { - /// See raw_ostream::write_impl. - void write_impl(const char *Ptr, size_t size) override; - void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override; - - /// Return the current position within the stream, not counting the bytes - /// currently in the buffer. - uint64_t current_pos() const override; - -public: - explicit raw_null_ostream() {} - ~raw_null_ostream() override; -}; - -class buffer_ostream : public raw_svector_ostream { - raw_ostream &OS; - SmallVector Buffer; - -public: - buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer), OS(OS) {} - ~buffer_ostream() override { OS << str(); } -}; - -} // end llvm namespace - -#endif // LLVM_SUPPORT_RAW_OSTREAM_H diff --git a/wpiutil/include/llvm/type_traits.h b/wpiutil/include/llvm/type_traits.h deleted file mode 100644 index d8ce4fa..0000000 --- a/wpiutil/include/llvm/type_traits.h +++ /dev/null @@ -1,95 +0,0 @@ -//===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides useful additions to the standard type_traits library. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_TYPE_TRAITS_H -#define LLVM_SUPPORT_TYPE_TRAITS_H - -#include -#include - -#include "llvm/Compiler.h" - -namespace llvm { - -/// isPodLike - This is a type trait that is used to determine whether a given -/// type can be copied around with memcpy instead of running ctors etc. -template -struct isPodLike { - // std::is_trivially_copyable is available in libc++ with clang, libstdc++ - // that comes with GCC 5. -#if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \ - (defined(__GNUC__) && __GNUC__ >= 5) - // If the compiler supports the is_trivially_copyable trait use it, as it - // matches the definition of isPodLike closely. - static const bool value = std::is_trivially_copyable::value; -#elif __has_feature(is_trivially_copyable) - // Use the internal name if the compiler supports is_trivially_copyable but we - // don't know if the standard library does. This is the case for clang in - // conjunction with libstdc++ from GCC 4.x. - static const bool value = __is_trivially_copyable(T); -#else - // If we don't know anything else, we can (at least) assume that all non-class - // types are PODs. - static const bool value = !std::is_class::value; -#endif -}; - -// std::pair's are pod-like if their elements are. -template -struct isPodLike > { - static const bool value = isPodLike::value && isPodLike::value; -}; - -/// \brief Metafunction that determines whether the given type is either an -/// integral type or an enumeration type, including enum classes. -/// -/// Note that this accepts potentially more integral types than is_integral -/// because it is based on being implicitly convertible to an integral type. -/// Also note that enum classes aren't implicitly convertible to integral types, -/// the value may therefore need to be explicitly converted before being used. -template class is_integral_or_enum { - typedef typename std::remove_reference::type UnderlyingT; - -public: - static const bool value = - !std::is_class::value && // Filter conversion operators. - !std::is_pointer::value && - !std::is_floating_point::value && - (std::is_enum::value || - std::is_convertible::value); -}; - -/// \brief If T is a pointer, just return it. If it is not, return T&. -template -struct add_lvalue_reference_if_not_pointer { typedef T &type; }; - -template -struct add_lvalue_reference_if_not_pointer< - T, typename std::enable_if::value>::type> { - typedef T type; -}; - -/// \brief If T is a pointer to X, return a pointer to const X. If it is not, -/// return const T. -template -struct add_const_past_pointer { typedef const T type; }; - -template -struct add_const_past_pointer< - T, typename std::enable_if::value>::type> { - typedef const typename std::remove_pointer::type *type; -}; - -} // namespace llvm - -#endif diff --git a/wpiutil/include/support/Base64.h b/wpiutil/include/support/Base64.h deleted file mode 100644 index 40cb252..0000000 --- a/wpiutil/include/support/Base64.h +++ /dev/null @@ -1,23 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_SUPPORT_BASE64_H_ -#define WPIUTIL_SUPPORT_BASE64_H_ - -#include -#include - -#include "llvm/StringRef.h" - -namespace wpi { - -std::size_t Base64Decode(llvm::StringRef encoded, std::string* plain); -void Base64Encode(llvm::StringRef plain, std::string* encoded); - -} // namespace wpi - -#endif // WPIUTIL_SUPPORT_BASE64_H_ diff --git a/wpiutil/include/support/ConcurrentQueue.h b/wpiutil/include/support/ConcurrentQueue.h deleted file mode 100644 index abe9580..0000000 --- a/wpiutil/include/support/ConcurrentQueue.h +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright (c) 2013 Juan Palacios juan.palacios.puyana@gmail.com -// Subject to the BSD 2-Clause License -// - see < http://opensource.org/licenses/BSD-2-Clause> -// - -#ifndef WPIUTIL_SUPPORT_CONCURRENT_QUEUE_H_ -#define WPIUTIL_SUPPORT_CONCURRENT_QUEUE_H_ - -#include -#include -#include -#include - -namespace wpi { - -template -class ConcurrentQueue { - public: - bool empty() const { - std::unique_lock mlock(mutex_); - return queue_.empty(); - } - - typename std::queue::size_type size() const { - std::unique_lock mlock(mutex_); - return queue_.size(); - } - - T pop() { - std::unique_lock mlock(mutex_); - while (queue_.empty()) { - cond_.wait(mlock); - } - auto item = std::move(queue_.front()); - queue_.pop(); - return item; - } - - void pop(T& item) { - std::unique_lock mlock(mutex_); - while (queue_.empty()) { - cond_.wait(mlock); - } - item = queue_.front(); - queue_.pop(); - } - - void push(const T& item) { - std::unique_lock mlock(mutex_); - queue_.push(item); - mlock.unlock(); - cond_.notify_one(); - } - - void push(T&& item) { - std::unique_lock mlock(mutex_); - queue_.push(std::forward(item)); - mlock.unlock(); - cond_.notify_one(); - } - - template - void emplace(Args&&... args) { - std::unique_lock mlock(mutex_); - queue_.emplace(std::forward(args)...); - mlock.unlock(); - cond_.notify_one(); - } - - ConcurrentQueue() = default; - ConcurrentQueue(const ConcurrentQueue&) = delete; - ConcurrentQueue& operator=(const ConcurrentQueue&) = delete; - - private: - std::queue queue_; - mutable std::mutex mutex_; - std::condition_variable cond_; -}; - -} // namespace wpi - -#endif // WPIUTIL_SUPPORT_CONCURRENT_QUEUE_H_ diff --git a/wpiutil/include/support/Logger.h b/wpiutil/include/support/Logger.h deleted file mode 100644 index c19ab9d..0000000 --- a/wpiutil/include/support/Logger.h +++ /dev/null @@ -1,84 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_SUPPORT_LOGGER_H_ -#define WPIUTIL_SUPPORT_LOGGER_H_ - -#include - -#include "llvm/raw_ostream.h" -#include "llvm/SmallString.h" - -namespace wpi { - -enum LogLevel { - WPI_LOG_CRITICAL = 50, - WPI_LOG_ERROR = 40, - WPI_LOG_WARNING = 30, - WPI_LOG_INFO = 20, - WPI_LOG_DEBUG = 10, - WPI_LOG_DEBUG1 = 9, - WPI_LOG_DEBUG2 = 8, - WPI_LOG_DEBUG3 = 7, - WPI_LOG_DEBUG4 = 6 -}; - -class Logger { - public: - typedef std::function LogFunc; - - void SetLogger(LogFunc func) { m_func = func; } - - void set_min_level(unsigned int level) { m_min_level = level; } - unsigned int min_level() const { return m_min_level; } - - void Log(unsigned int level, const char* file, unsigned int line, - const char* msg) { - if (!m_func || level < m_min_level) return; - m_func(level, file, line, msg); - } - - bool HasLogger() const { return m_func != nullptr; } - - private: - LogFunc m_func; - unsigned int m_min_level = 20; -}; - -#define WPI_LOG(logger_inst, level, x) \ - do { \ - ::wpi::Logger& WPI_logger_ = logger_inst; \ - if (WPI_logger_.min_level() <= level && WPI_logger_.HasLogger()) { \ - llvm::SmallString<128> log_buf_; \ - llvm::raw_svector_ostream log_os_{log_buf_}; \ - log_os_ << x; \ - WPI_logger_.Log(level, __FILE__, __LINE__, log_buf_.c_str()); \ - } \ - } while (0) - -#define WPI_ERROR(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_ERROR, x) -#define WPI_WARNING(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_WARNING, x) -#define WPI_INFO(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_INFO, x) - -#ifdef NDEBUG -#define WPI_DEBUG(inst, x) do {} while (0) -#define WPI_DEBUG1(inst, x) do {} while (0) -#define WPI_DEBUG2(inst, x) do {} while (0) -#define WPI_DEBUG3(inst, x) do {} while (0) -#define WPI_DEBUG4(inst, x) do {} while (0) -#else -#define WPI_DEBUG(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG, x) -#define WPI_DEBUG1(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG1, x) -#define WPI_DEBUG2(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG2, x) -#define WPI_DEBUG3(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG3, x) -#define WPI_DEBUG4(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG4, x) -#endif - -} // namespace wpi - -#endif // WPIUTIL_SUPPORT_LOGGER_H_ diff --git a/wpiutil/include/support/SafeThread.h b/wpiutil/include/support/SafeThread.h deleted file mode 100644 index 0f39bc6..0000000 --- a/wpiutil/include/support/SafeThread.h +++ /dev/null @@ -1,132 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_SUPPORT_SAFETHREAD_H_ -#define WPIUTIL_SUPPORT_SAFETHREAD_H_ - -#include -#include -#include -#include - -namespace wpi { - -// Base class for SafeThreadOwner threads. -class SafeThread { - public: - SafeThread() { m_active = true; } - virtual ~SafeThread() = default; - virtual void Main() = 0; - - std::mutex m_mutex; - std::atomic_bool m_active; - std::condition_variable m_cond; -}; - -namespace detail { - -// Non-template proxy base class for common proxy code. -class SafeThreadProxyBase { - public: - SafeThreadProxyBase(SafeThread* thr) : m_thread(thr) { - if (!m_thread) return; - std::unique_lock(m_thread->m_mutex).swap(m_lock); - if (!m_thread->m_active) { - m_lock.unlock(); - m_thread = nullptr; - return; - } - } - explicit operator bool() const { return m_thread != nullptr; } - std::unique_lock& GetLock() { return m_lock; } - - protected: - SafeThread* m_thread; - std::unique_lock m_lock; -}; - -// A proxy for SafeThread. -// Also serves as a scoped lock on SafeThread::m_mutex. -template -class SafeThreadProxy : public SafeThreadProxyBase { - public: - SafeThreadProxy(SafeThread* thr) : SafeThreadProxyBase(thr) {} - T& operator*() const { return *static_cast(m_thread); } - T* operator->() const { return static_cast(m_thread); } -}; - -// Non-template owner base class for common owner code. -class SafeThreadOwnerBase { - public: - void Stop(); - - SafeThreadOwnerBase() { m_thread = nullptr; } - SafeThreadOwnerBase(const SafeThreadOwnerBase&) = delete; - SafeThreadOwnerBase& operator=(const SafeThreadOwnerBase&) = delete; - SafeThreadOwnerBase(SafeThreadOwnerBase&& other) - : m_thread(other.m_thread.exchange(nullptr)) {} - SafeThreadOwnerBase& operator=(SafeThreadOwnerBase other) { - SafeThread* otherthr = other.m_thread.exchange(nullptr); - SafeThread* curthr = m_thread.exchange(otherthr); - other.m_thread.exchange(curthr); // other destructor will clean up - return *this; - } - ~SafeThreadOwnerBase() { Stop(); } - - explicit operator bool() const { return m_thread.load(); } - - protected: - void Start(SafeThread* thr); - SafeThread* GetThread() const { return m_thread.load(); } - std::thread::native_handle_type GetNativeThreadHandle() const { - return m_nativeHandle; - } - - private: - std::atomic m_thread; - std::atomic m_nativeHandle; -}; - -inline void SafeThreadOwnerBase::Start(SafeThread* thr) { - SafeThread* curthr = nullptr; - SafeThread* newthr = thr; - if (!m_thread.compare_exchange_strong(curthr, newthr)) { - delete newthr; - return; - } - std::thread stdThread([=]() { - newthr->Main(); - delete newthr; - }); - m_nativeHandle = stdThread.native_handle(); - stdThread.detach(); -} - -inline void SafeThreadOwnerBase::Stop() { - SafeThread* thr = m_thread.exchange(nullptr); - if (!thr) return; - thr->m_active = false; - thr->m_cond.notify_one(); -} - -} // namespace detail - -template -class SafeThreadOwner : public detail::SafeThreadOwnerBase { - public: - void Start() { Start(new T); } - void Start(T* thr) { detail::SafeThreadOwnerBase::Start(thr); } - - using Proxy = typename detail::SafeThreadProxy; - Proxy GetThread() const { - return Proxy(detail::SafeThreadOwnerBase::GetThread()); - } -}; - -} // namespace wpi - -#endif // WPIUTIL_SUPPORT_SAFETHREAD_H_ diff --git a/wpiutil/include/support/atomic_static.h b/wpiutil/include/support/atomic_static.h deleted file mode 100644 index 146a1de..0000000 --- a/wpiutil/include/support/atomic_static.h +++ /dev/null @@ -1,49 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_SUPPORT_ATOMIC_STATIC_H_ -#define WPIUTIL_SUPPORT_ATOMIC_STATIC_H_ - -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) - -// Just use a local static. This is thread-safe per -// http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/ - -// Per https://msdn.microsoft.com/en-us/library/Hh567368.aspx "Magic Statics" -// are supported in Visual Studio 2015 but not in earlier versions. -#define ATOMIC_STATIC(cls, inst) static cls inst -#define ATOMIC_STATIC_DECL(cls) -#define ATOMIC_STATIC_INIT(cls) - -#else -// From http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/ -#include -#include - -#define ATOMIC_STATIC(cls, inst) \ - cls* inst##tmp = m_instance.load(std::memory_order_acquire); \ - if (inst##tmp == nullptr) { \ - std::lock_guard lock(m_instance_mutex); \ - inst##tmp = m_instance.load(std::memory_order_relaxed); \ - if (inst##tmp == nullptr) { \ - inst##tmp = new cls; \ - m_instance.store(inst##tmp, std::memory_order_release); \ - } \ - } \ - cls& inst = *inst##tmp - -#define ATOMIC_STATIC_DECL(cls) \ - static std::atomic m_instance; \ - static std::mutex m_instance_mutex; - -#define ATOMIC_STATIC_INIT(cls) \ - std::atomic cls::m_instance; \ - std::mutex cls::m_instance_mutex; - -#endif - -#endif // WPIUTIL_SUPPORT_ATOMIC_STATIC_H_ diff --git a/wpiutil/include/support/deprecated.h b/wpiutil/include/support/deprecated.h deleted file mode 100644 index 4a22b73..0000000 --- a/wpiutil/include/support/deprecated.h +++ /dev/null @@ -1,33 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef DEPRECATED_H_ -#define DEPRECATED_H_ - -// [[deprecated(msg)]] is a C++14 feature not supported by MSVC or GCC < 4.9. -// We provide an equivalent warning implementation for those compilers here. -#ifndef WPI_DEPRECATED - #if defined(_MSC_VER) - #define WPI_DEPRECATED(msg) __declspec(deprecated(msg)) - #elif defined(__GNUC__) - #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 8) - #if __cplusplus > 201103L - #define WPI_DEPRECATED(msg) [[deprecated(msg)]] - #else - #define WPI_DEPRECATED(msg) [[gnu::deprecated(msg)]] - #endif - #else - #define WPI_DEPRECATED(msg) __attribute__((deprecated(msg))) - #endif - #elif __cplusplus > 201103L - #define WPI_DEPRECATED(msg) [[deprecated(msg)]] - #else - #define WPI_DEPRECATED(msg) /*nothing*/ - #endif -#endif - -#endif // DEPRECATED_H_ diff --git a/wpiutil/include/support/jni_util.h b/wpiutil/include/support/jni_util.h deleted file mode 100644 index 3523894..0000000 --- a/wpiutil/include/support/jni_util.h +++ /dev/null @@ -1,608 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2016. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_SUPPORT_JNI_UTIL_H_ -#define WPIUTIL_SUPPORT_JNI_UTIL_H_ - -#include -#include -#include -#include -#include - -#include - -#include "llvm/ArrayRef.h" -#include "llvm/ConvertUTF.h" -#include "llvm/raw_ostream.h" -#include "llvm/SmallString.h" -#include "llvm/SmallVector.h" -#include "llvm/StringRef.h" -#include "support/atomic_static.h" -#include "support/SafeThread.h" - -namespace wpi { -namespace java { - -// Gets a Java stack trace. This version also provides the last function -// in the stack trace not starting with excludeFuncPrefix (useful for e.g. -// finding the first user call to a series of library functions). -template -std::string GetJavaStackTrace(JNIEnv* env, std::string* func); - -// Gets a Java stack trace. -inline std::string GetJavaStackTrace(JNIEnv* env) { - return GetJavaStackTrace(env, nullptr); -} - -// Finds a class and keep it as a global reference. -// Use with caution, as the destructor does NOT call DeleteGlobalRef due -// to potential shutdown issues with doing so. -class JClass { - public: - JClass() = default; - - JClass(JNIEnv* env, const char* name) { - jclass local = env->FindClass(name); - if (!local) return; - m_cls = static_cast(env->NewGlobalRef(local)); - env->DeleteLocalRef(local); - } - - void free(JNIEnv *env) { - if (m_cls) env->DeleteGlobalRef(m_cls); - m_cls = nullptr; - } - - explicit operator bool() const { return m_cls; } - - operator jclass() const { return m_cls; } - - protected: - jclass m_cls = nullptr; -}; - -// Container class for cleaning up Java local references. -// The destructor calls DeleteLocalRef. -template -class JLocal { - public: - JLocal(JNIEnv *env, T obj) : m_env(env), m_obj(obj) {} - JLocal(const JLocal&) = delete; - JLocal(JLocal&& oth) : m_env(oth.m_env), m_obj(oth.m_obj) { - oth.m_obj = nullptr; - } - JLocal& operator=(const JLocal&) = delete; - JLocal& operator=(JLocal&& oth) { - m_env = oth.m_env; - m_obj = oth.m_obj; - oth.m_obj = nullptr; - return *this; - } - ~JLocal() { - if (m_obj) m_env->DeleteLocalRef(m_obj); - } - operator T() { return m_obj; } - T obj() { return m_obj; } - - private: - JNIEnv *m_env; - T m_obj; -}; - -// -// Conversions from Java objects to C++ -// - -// Java string (jstring) reference. The string is provided as UTF8. -// This is not actually a reference, as it makes a copy of the string -// characters, but it's named this way for consistency. -class JStringRef { - public: - JStringRef(JNIEnv *env, jstring str) { - if (str) { - jsize size = env->GetStringLength(str); - const jchar *chars = env->GetStringCritical(str, nullptr); - if (chars) { - llvm::convertUTF16ToUTF8String(llvm::makeArrayRef(chars, size), m_str); - env->ReleaseStringCritical(str, chars); - } - } else { - llvm::errs() << "JStringRef was passed a null pointer at \n" - << GetJavaStackTrace(env); - } - // Ensure str is null-terminated. - m_str.push_back('\0'); - m_str.pop_back(); - } - - operator llvm::StringRef() const { return m_str; } - llvm::StringRef str() const { return m_str; } - const char* c_str() const { return m_str.data(); } - size_t size() const { return m_str.size(); } - - private: - llvm::SmallString<128> m_str; -}; - -// Details for J*ArrayRef and CriticalJ*ArrayRef -namespace detail { - -template -class JArrayRefInner {}; - -// Specialization of JArrayRefBase to provide StringRef conversion. -template -class JArrayRefInner { - public: - operator llvm::StringRef() const { return str(); } - - llvm::StringRef str() const { - auto arr = static_cast(this)->array(); - if (arr.empty()) return llvm::StringRef{}; - return llvm::StringRef{reinterpret_cast(arr.data()), - arr.size()}; - } -}; - -// Base class for J*ArrayRef and CriticalJ*ArrayRef -template -class JArrayRefBase : public JArrayRefInner, T> { - public: - explicit operator bool() const { return this->m_elements != nullptr; } - - operator llvm::ArrayRef() const { return array(); } - - llvm::ArrayRef array() const { - if (!this->m_elements) return llvm::ArrayRef{}; - return llvm::ArrayRef{this->m_elements, this->m_size}; - } - - JArrayRefBase(const JArrayRefBase&) = delete; - JArrayRefBase& operator=(const JArrayRefBase&) = delete; - - JArrayRefBase(JArrayRefBase&& oth) - : m_env(oth.m_env), - m_jarr(oth.m_jarr), - m_size(oth.m_size), - m_elements(oth.m_elements) { - oth.m_jarr = nullptr; - oth.m_elements = nullptr; - } - - JArrayRefBase& operator=(JArrayRefBase&& oth) { - this->m_env = oth.m_env; - this->m_jarr = oth.m_jarr; - this->m_size = oth.m_size; - this->m_elements = oth.m_elements; - oth.m_jarr = nullptr; - oth.m_elements = nullptr; - } - - protected: - JArrayRefBase(JNIEnv *env, T* elements, size_t size) { - this->m_env = env; - this->m_jarr = nullptr; - this->m_size = size; - this->m_elements = elements; - } - - JArrayRefBase(JNIEnv *env, jarray jarr) { - this->m_env = env; - this->m_jarr = jarr; - this->m_size = jarr ? env->GetArrayLength(jarr) : 0; - this->m_elements = nullptr; - } - - JNIEnv *m_env; - jarray m_jarr = nullptr; - size_t m_size; - T *m_elements; -}; - -} // namespace detail - -// Java array / DirectBuffer reference. - -#define WPI_JNI_JARRAYREF(T, F) \ - class J##F##ArrayRef : public detail::JArrayRefBase { \ - public: \ - J##F##ArrayRef(JNIEnv* env, jobject bb, int len) \ - : detail::JArrayRefBase( \ - env, \ - static_cast(bb ? env->GetDirectBufferAddress(bb) : nullptr), \ - len) { \ - if (!bb) \ - llvm::errs() << "JArrayRef was passed a null pointer at \n" \ - << GetJavaStackTrace(env); \ - } \ - J##F##ArrayRef(JNIEnv* env, T##Array jarr) \ - : detail::JArrayRefBase(env, jarr) { \ - if (jarr) \ - m_elements = env->Get##F##ArrayElements(jarr, nullptr); \ - else \ - llvm::errs() << "JArrayRef was passed a null pointer at \n" \ - << GetJavaStackTrace(env); \ - } \ - ~J##F##ArrayRef() { \ - if (m_jarr && m_elements) \ - m_env->Release##F##ArrayElements(static_cast(m_jarr), \ - m_elements, JNI_ABORT); \ - } \ - }; \ - \ - class CriticalJ##F##ArrayRef : public detail::JArrayRefBase { \ - public: \ - CriticalJ##F##ArrayRef(JNIEnv* env, T##Array jarr) \ - : detail::JArrayRefBase(env, jarr) { \ - if (jarr) \ - m_elements = \ - static_cast(env->GetPrimitiveArrayCritical(jarr, nullptr)); \ - else \ - llvm::errs() << "JArrayRef was passed a null pointer at \n" \ - << GetJavaStackTrace(env); \ - } \ - ~CriticalJ##F##ArrayRef() { \ - if (m_jarr && m_elements) \ - m_env->ReleasePrimitiveArrayCritical(m_jarr, m_elements, JNI_ABORT); \ - } \ - }; - -WPI_JNI_JARRAYREF(jboolean, Boolean) -WPI_JNI_JARRAYREF(jbyte, Byte) -WPI_JNI_JARRAYREF(jshort, Short) -WPI_JNI_JARRAYREF(jint, Int) -WPI_JNI_JARRAYREF(jlong, Long) -WPI_JNI_JARRAYREF(jfloat, Float) -WPI_JNI_JARRAYREF(jdouble, Double) - -#undef WPI_JNI_JARRAYREF - -// -// Conversions from C++ to Java objects -// - -// Convert a UTF8 string into a jstring. -inline jstring MakeJString(JNIEnv *env, llvm::StringRef str) { - llvm::SmallVector chars; - llvm::convertUTF8ToUTF16String(str, chars); - return env->NewString(chars.begin(), chars.size()); -} - -// details for MakeJIntArray -namespace detail { - -// Slow path (get primitive array and set individual elements). This -// is used if the input type is not an integer of the same size (note -// signed/unsigned is ignored). -template ::value && sizeof(jint) == sizeof(T))> -struct ConvertIntArray { - static jintArray ToJava(JNIEnv *env, llvm::ArrayRef arr) { - jintArray jarr = env->NewIntArray(arr.size()); - if (!jarr) return nullptr; - jint *elements = - static_cast(env->GetPrimitiveArrayCritical(jarr, nullptr)); - if (!elements) return nullptr; - for (size_t i = 0; i < arr.size(); ++i) - elements[i] = static_cast(arr[i]); - env->ReleasePrimitiveArrayCritical(jarr, elements, 0); - return jarr; - } -}; - -// Fast path (use SetIntArrayRegion) -template -struct ConvertIntArray { - static jintArray ToJava(JNIEnv *env, llvm::ArrayRef arr) { - jintArray jarr = env->NewIntArray(arr.size()); - if (!jarr) return nullptr; - env->SetIntArrayRegion(jarr, 0, arr.size(), - reinterpret_cast(arr.data())); - return jarr; - } -}; - -} // namespace detail - -// Convert an ArrayRef to a jintArray. -template -inline jintArray MakeJIntArray(JNIEnv *env, llvm::ArrayRef arr) { - return detail::ConvertIntArray::ToJava(env, arr); -} - -// Convert a SmallVector to a jintArray. This is required in addition to -// ArrayRef because template resolution occurs prior to implicit conversions. -template -inline jintArray MakeJIntArray(JNIEnv *env, - const llvm::SmallVectorImpl &arr) { - return detail::ConvertIntArray::ToJava(env, arr); -} - -// Convert a std::vector to a jintArray. This is required in addition to -// ArrayRef because template resolution occurs prior to implicit conversions. -template -inline jintArray MakeJIntArray(JNIEnv *env, const std::vector &arr) { - return detail::ConvertIntArray::ToJava(env, arr); -} - -// Convert a StringRef into a jbyteArray. -inline jbyteArray MakeJByteArray(JNIEnv *env, llvm::StringRef str) { - jbyteArray jarr = env->NewByteArray(str.size()); - if (!jarr) return nullptr; - env->SetByteArrayRegion(jarr, 0, str.size(), - reinterpret_cast(str.data())); - return jarr; -} - -// Convert an array of integers into a jbooleanArray. -inline jbooleanArray MakeJBooleanArray(JNIEnv *env, llvm::ArrayRef arr) -{ - jbooleanArray jarr = env->NewBooleanArray(arr.size()); - if (!jarr) return nullptr; - jboolean *elements = - static_cast(env->GetPrimitiveArrayCritical(jarr, nullptr)); - if (!elements) return nullptr; - for (size_t i = 0; i < arr.size(); ++i) - elements[i] = arr[i] ? JNI_TRUE : JNI_FALSE; - env->ReleasePrimitiveArrayCritical(jarr, elements, 0); - return jarr; -} - -// Convert an array of booleans into a jbooleanArray. -inline jbooleanArray MakeJBooleanArray(JNIEnv *env, llvm::ArrayRef arr) -{ - jbooleanArray jarr = env->NewBooleanArray(arr.size()); - if (!jarr) return nullptr; - jboolean *elements = - static_cast(env->GetPrimitiveArrayCritical(jarr, nullptr)); - if (!elements) return nullptr; - for (size_t i = 0; i < arr.size(); ++i) - elements[i] = arr[i] ? JNI_TRUE : JNI_FALSE; - env->ReleasePrimitiveArrayCritical(jarr, elements, 0); - return jarr; -} - -// Other MakeJ*Array conversions. - -#define WPI_JNI_MAKEJARRAY(T, F) \ - inline T##Array MakeJ##F##Array(JNIEnv *env, llvm::ArrayRef arr) { \ - T##Array jarr = env->New##F##Array(arr.size()); \ - if (!jarr) return nullptr; \ - env->Set##F##ArrayRegion(jarr, 0, arr.size(), arr.data()); \ - return jarr; \ - } - -WPI_JNI_MAKEJARRAY(jboolean, Boolean) -WPI_JNI_MAKEJARRAY(jbyte, Byte) -WPI_JNI_MAKEJARRAY(jshort, Short) -WPI_JNI_MAKEJARRAY(jlong, Long) -WPI_JNI_MAKEJARRAY(jfloat, Float) -WPI_JNI_MAKEJARRAY(jdouble, Double) - -#undef WPI_JNI_MAKEJARRAY - -// Convert an array of std::string into a jarray of jstring. -inline jobjectArray MakeJStringArray(JNIEnv *env, - llvm::ArrayRef arr) { - static JClass stringCls{env, "java/lang/String"}; - if (!stringCls) return nullptr; - jobjectArray jarr = env->NewObjectArray(arr.size(), stringCls, nullptr); - if (!jarr) return nullptr; - for (std::size_t i = 0; i < arr.size(); ++i) { - JLocal elem{env, MakeJString(env, arr[i])}; - env->SetObjectArrayElement(jarr, i, elem.obj()); - } - return jarr; -} - -// Generic callback thread implementation. -// -// JNI's AttachCurrentThread() creates a Java Thread object on every -// invocation, which is both time inefficient and causes issues with Eclipse -// (which tries to keep a thread list up-to-date and thus gets swamped). -// -// Instead, this class attaches just once. When a hardware notification -// occurs, a condition variable wakes up this thread and this thread actually -// makes the call into Java. -// -// The template parameter T is the message being passed to the callback, but -// also needs to provide the following functions: -// static JavaVM* GetJVM(); -// static const char* GetName(); -// void CallJava(JNIEnv *env, jobject func, jmethodID mid); -// -// When creating this, ATOMIC_STATIC_INIT() needs to be performed on the -// templated class as well. -template -class JCallbackThread : public SafeThread { - public: - void Main(); - - std::queue m_queue; - jobject m_func = nullptr; - jmethodID m_mid; -}; - -template -class JCallbackManager : public SafeThreadOwner> { - public: - void SetFunc(JNIEnv* env, jobject func, jmethodID mid); - - template - void Send(Args&&... args); -}; - -template -void JCallbackManager::SetFunc(JNIEnv* env, jobject func, jmethodID mid) { - auto thr = this->GetThread(); - if (!thr) return; - // free global reference - if (thr->m_func) env->DeleteGlobalRef(thr->m_func); - // create global reference - thr->m_func = env->NewGlobalRef(func); - thr->m_mid = mid; -} - -template -template -void JCallbackManager::Send(Args&&... args) { - auto thr = this->GetThread(); - if (!thr) return; - thr->m_queue.emplace(std::forward(args)...); - thr->m_cond.notify_one(); -} - -template -void JCallbackThread::Main() { - JNIEnv *env; - JavaVMAttachArgs args; - args.version = JNI_VERSION_1_2; - args.name = const_cast(T::GetName()); - args.group = nullptr; - jint rs = T::GetJVM()->AttachCurrentThreadAsDaemon((void**)&env, &args); - if (rs != JNI_OK) return; - - std::unique_lock lock(m_mutex); - while (m_active) { - m_cond.wait(lock, [&] { return !(m_active && m_queue.empty()); }); - if (!m_active) break; - while (!m_queue.empty()) { - if (!m_active) break; - auto item = std::move(m_queue.front()); - m_queue.pop(); - auto func = m_func; - auto mid = m_mid; - lock.unlock(); // don't hold mutex during callback execution - item.CallJava(env, func, mid); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - env->ExceptionClear(); - } - lock.lock(); - } - } - - JavaVM* jvm = T::GetJVM(); - if (jvm) jvm->DetachCurrentThread(); -} - -template -class JSingletonCallbackManager : public JCallbackManager { - public: - static JSingletonCallbackManager& GetInstance() { - ATOMIC_STATIC(JSingletonCallbackManager, instance); - return instance; - } - - private: - ATOMIC_STATIC_DECL(JSingletonCallbackManager) -}; - -template -std::string GetJavaStackTrace(JNIEnv* env, std::string* func) { - // create a throwable - static JClass throwableCls(env, "java/lang/Throwable"); - if (!throwableCls) return ""; - static jmethodID constructorId = nullptr; - if (!constructorId) - constructorId = env->GetMethodID(throwableCls, "", "()V"); - JLocal throwable(env, env->NewObject(throwableCls, constructorId)); - - // retrieve information from the exception. - // get method id - // getStackTrace returns an array of StackTraceElement - static jmethodID getStackTraceId = nullptr; - if (!getStackTraceId) - getStackTraceId = env->GetMethodID(throwableCls, "getStackTrace", - "()[Ljava/lang/StackTraceElement;"); - - // call getStackTrace - JLocal stackTrace( - env, static_cast( - env->CallObjectMethod(throwable, getStackTraceId))); - - if (!stackTrace) return ""; - - // get length of the array - jsize stackTraceLength = env->GetArrayLength(stackTrace); - - // get toString methodId of StackTraceElement class - static JClass stackTraceElementCls(env, "java/lang/StackTraceElement"); - if (!stackTraceElementCls) return ""; - static jmethodID toStringId = nullptr; - if (!toStringId) - toStringId = env->GetMethodID(stackTraceElementCls, "toString", - "()Ljava/lang/String;"); - - bool haveLoc = false; - std::string buf; - llvm::raw_string_ostream oss(buf); - for (jsize i = 0; i < stackTraceLength; i++) { - // add the result of toString method of each element in the result - JLocal curStackTraceElement( - env, env->GetObjectArrayElement(stackTrace, i)); - - // call to string on the object - JLocal stackElementString( - env, static_cast( - env->CallObjectMethod(curStackTraceElement, toStringId))); - - if (!stackElementString) return ""; - - // add a line to res - JStringRef elem(env, stackElementString); - oss << elem << '\n'; - - if (func) { - // func is caller of immediate caller (if there was one) - // or, if we see it, the first user function - if (i == 1) - *func = elem.str(); - else if (i > 1 && !haveLoc && excludeFuncPrefix != nullptr && - !elem.str().startswith(excludeFuncPrefix)) { - *func = elem.str(); - haveLoc = true; - } - } - } - - return oss.str(); -} - -// Finds an exception class and keep it as a global reference. -// Similar to JClass, but provides Throw methods. -// Use with caution, as the destructor does NOT call DeleteGlobalRef due -// to potential shutdown issues with doing so. -class JException : public JClass { - public: - JException() = default; - JException(JNIEnv* env, const char* name) : JClass(env, name) { - if (m_cls) - m_constructor = - env->GetMethodID(m_cls, "", "(Ljava/lang/String;)V"); - } - - void Throw(JNIEnv* env, jstring msg) { - jobject exception = env->NewObject(m_cls, m_constructor, msg); - env->Throw(static_cast(exception)); - } - - void Throw(JNIEnv* env, llvm::StringRef msg) { - Throw(env, MakeJString(env, msg)); - } - - explicit operator bool() const { return m_constructor; } - - private: - jmethodID m_constructor = nullptr; -}; - -} // namespace java -} // namespace wpi - -#endif // WPIUTIL_SUPPORT_JNI_UTIL_H_ diff --git a/wpiutil/include/support/leb128.h b/wpiutil/include/support/leb128.h deleted file mode 100644 index de08a23..0000000 --- a/wpiutil/include/support/leb128.h +++ /dev/null @@ -1,26 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_SUPPORT_LEB128_H_ -#define WPIUTIL_SUPPORT_LEB128_H_ - -#include - -#include "llvm/SmallVector.h" - -namespace wpi { - -class raw_istream; - -std::size_t SizeUleb128(unsigned long val); -std::size_t WriteUleb128(llvm::SmallVectorImpl& dest, unsigned long val); -std::size_t ReadUleb128(const char* addr, unsigned long* ret); -bool ReadUleb128(raw_istream& is, unsigned long* ret); - -} // namespace wpi - -#endif // WPIUTIL_SUPPORT_LEB128_H_ diff --git a/wpiutil/include/support/raw_istream.h b/wpiutil/include/support/raw_istream.h deleted file mode 100644 index d9a9b9c..0000000 --- a/wpiutil/include/support/raw_istream.h +++ /dev/null @@ -1,99 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_SUPPORT_RAW_ISTREAM_H_ -#define WPIUTIL_SUPPORT_RAW_ISTREAM_H_ - -#include -#include - -namespace wpi { - -class raw_istream { - public: - raw_istream() = default; - virtual ~raw_istream() = default; - - raw_istream& read(char& c) { - read_impl(&c, 1); - return *this; - } - - raw_istream& read(unsigned char& c) { - read_impl(&c, 1); - return *this; - } - - raw_istream& read(signed char& c) { - read_impl(&c, 1); - return *this; - } - - raw_istream& read(void* data, std::size_t len) { - read_impl(data, len); - return *this; - } - - std::size_t readsome(void* data, std::size_t len) { - std::size_t readlen = std::min(in_avail(), len); - if (readlen == 0) return 0; - read_impl(data, readlen); - return readlen; - }; - - virtual void close() = 0; - virtual std::size_t in_avail() const = 0; - - bool has_error() const { return m_error; } - void clear_error() { m_error = false; } - - raw_istream(const raw_istream&) = delete; - raw_istream& operator=(const raw_istream&) = delete; - - protected: - void error_detected() { m_error = true; } - - private: - virtual void read_impl(void* data, std::size_t len) = 0; - - bool m_error = false; -}; - -class raw_mem_istream : public raw_istream { - public: - raw_mem_istream(const char* mem, std::size_t len) : m_cur(mem), m_left(len) {} - void close() override; - std::size_t in_avail() const override; - - private: - void read_impl(void* data, std::size_t len) override; - - const char* m_cur; - std::size_t m_left; -}; - -class raw_fd_istream : public raw_istream { - public: - raw_fd_istream(int fd, bool shouldClose, std::size_t bufSize = 4096); - ~raw_fd_istream() override; - void close() override; - std::size_t in_avail() const override; - - private: - void read_impl(void* data, std::size_t len) override; - - char* m_buf; - char* m_cur; - char* m_end; - std::size_t m_bufSize; - int m_fd; - bool m_shouldClose; -}; - -} // namespace wpi - -#endif // WPIUTIL_SUPPORT_RAW_ISTREAM_H_ diff --git a/wpiutil/include/support/raw_socket_istream.h b/wpiutil/include/support/raw_socket_istream.h deleted file mode 100644 index 475d3d0..0000000 --- a/wpiutil/include/support/raw_socket_istream.h +++ /dev/null @@ -1,34 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_SUPPORT_RAW_SOCKET_ISTREAM_H_ -#define WPIUTIL_SUPPORT_RAW_SOCKET_ISTREAM_H_ - -#include "support/raw_istream.h" - -namespace wpi { - -class NetworkStream; - -class raw_socket_istream : public raw_istream { - public: - explicit raw_socket_istream(NetworkStream& stream, int timeout = 0) - : m_stream(stream), m_timeout(timeout) {} - - void close() override; - std::size_t in_avail() const override; - - private: - void read_impl(void* data, std::size_t len) override; - - NetworkStream& m_stream; - int m_timeout; -}; - -} // namespace wpi - -#endif // WPIUTIL_SUPPORT_RAW_SOCKET_ISTREAM_H_ diff --git a/wpiutil/include/support/raw_socket_ostream.h b/wpiutil/include/support/raw_socket_ostream.h deleted file mode 100644 index 65793d3..0000000 --- a/wpiutil/include/support/raw_socket_ostream.h +++ /dev/null @@ -1,42 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2016. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_SUPPORT_RAW_SOCKET_OSTREAM_H_ -#define WPIUTIL_SUPPORT_RAW_SOCKET_OSTREAM_H_ - -#include "llvm/raw_ostream.h" - -namespace wpi { - -class NetworkStream; - -class raw_socket_ostream : public llvm::raw_ostream { - public: - raw_socket_ostream(NetworkStream& stream, bool shouldClose) - : m_stream(stream), m_shouldClose(shouldClose) {} - ~raw_socket_ostream(); - - void close(); - - bool has_error() const { return m_error; } - void clear_error() { m_error = false; } - - protected: - void error_detected() { m_error = true; } - - private: - void write_impl(const char* data, std::size_t len) override; - uint64_t current_pos() const override; - - NetworkStream& m_stream; - bool m_error = false; - bool m_shouldClose; -}; - -} // namespace wpi - -#endif // WPIUTIL_SUPPORT_RAW_SOCKET_OSTREAM_H_ diff --git a/wpiutil/include/support/timestamp.h b/wpiutil/include/support/timestamp.h deleted file mode 100644 index 526d6e5..0000000 --- a/wpiutil/include/support/timestamp.h +++ /dev/null @@ -1,28 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ -#ifndef WPIUTIL_SUPPORT_TIMESTAMP_H_ -#define WPIUTIL_SUPPORT_TIMESTAMP_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -unsigned long long WPI_Now(void); - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus -namespace wpi { - -unsigned long long Now(); - -} // namespace wpi -#endif - -#endif // WPIUTIL_SUPPORT_TIMESTAMP_H_ diff --git a/wpiutil/include/tcpsockets/NetworkAcceptor.h b/wpiutil/include/tcpsockets/NetworkAcceptor.h deleted file mode 100644 index f4d9120..0000000 --- a/wpiutil/include/tcpsockets/NetworkAcceptor.h +++ /dev/null @@ -1,30 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_TCPSOCKETS_NETWORKACCEPTOR_H_ -#define WPIUTIL_TCPSOCKETS_NETWORKACCEPTOR_H_ - -#include "tcpsockets/NetworkStream.h" - -namespace wpi { - -class NetworkAcceptor { - public: - NetworkAcceptor() = default; - virtual ~NetworkAcceptor() = default; - - virtual int start() = 0; - virtual void shutdown() = 0; - virtual std::unique_ptr accept() = 0; - - NetworkAcceptor(const NetworkAcceptor&) = delete; - NetworkAcceptor& operator=(const NetworkAcceptor&) = delete; -}; - -} // namespace wpi - -#endif // WPIUTIL_TCPSOCKETS_NETWORKACCEPTOR_H_ diff --git a/wpiutil/include/tcpsockets/NetworkStream.h b/wpiutil/include/tcpsockets/NetworkStream.h deleted file mode 100644 index 03b3a93..0000000 --- a/wpiutil/include/tcpsockets/NetworkStream.h +++ /dev/null @@ -1,48 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_TCPSOCKETS_NETWORKSTREAM_H_ -#define WPIUTIL_TCPSOCKETS_NETWORKSTREAM_H_ - -#include - -#include "llvm/StringRef.h" - -namespace wpi { - -class NetworkStream { - public: - NetworkStream() = default; - virtual ~NetworkStream() = default; - - enum Error { - kConnectionClosed = 0, - kConnectionReset = -1, - kConnectionTimedOut = -2, - kWouldBlock = -3 - }; - - virtual std::size_t send(const char* buffer, std::size_t len, Error* err) = 0; - virtual std::size_t receive(char* buffer, std::size_t len, Error* err, - int timeout = 0) = 0; - virtual void close() = 0; - - virtual llvm::StringRef getPeerIP() const = 0; - virtual int getPeerPort() const = 0; - virtual void setNoDelay() = 0; - - // returns false on failure - virtual bool setBlocking(bool enabled) = 0; - virtual int getNativeHandle() const = 0; - - NetworkStream(const NetworkStream&) = delete; - NetworkStream& operator=(const NetworkStream&) = delete; -}; - -} // namespace wpi - -#endif // WPIUTIL_TCPSOCKETS_NETWORKSTREAM_H_ diff --git a/wpiutil/include/tcpsockets/SocketError.h b/wpiutil/include/tcpsockets/SocketError.h deleted file mode 100644 index 3d87b2d..0000000 --- a/wpiutil/include/tcpsockets/SocketError.h +++ /dev/null @@ -1,37 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_TCPSOCKETS_SOCKETERROR_H_ -#define WPIUTIL_TCPSOCKETS_SOCKETERROR_H_ - -#include - -#ifdef _WIN32 -#include -#else -#include -#endif - -namespace wpi { - -static inline int SocketErrno() { -#ifdef _WIN32 - return WSAGetLastError(); -#else - return errno; -#endif -} - -std::string SocketStrerror(int code); - -static inline std::string SocketStrerror() { - return SocketStrerror(SocketErrno()); -} - -} // namespace wpi - -#endif // WPIUTIL_TCPSOCKETS_SOCKETERROR_H_ diff --git a/wpiutil/include/tcpsockets/TCPAcceptor.h b/wpiutil/include/tcpsockets/TCPAcceptor.h deleted file mode 100644 index 99403a3..0000000 --- a/wpiutil/include/tcpsockets/TCPAcceptor.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - TCPAcceptor.h - - TCPAcceptor class interface. TCPAcceptor provides methods to passively - establish TCP/IP connections with clients. - - ------------------------------------------ - - Copyright © 2013 [Vic Hargrave - http://vichargrave.com] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#ifndef WPIUTIL_TCPSOCKETS_TCPACCEPTOR_H_ -#define WPIUTIL_TCPSOCKETS_TCPACCEPTOR_H_ - -#include -#include -#include - -#include "tcpsockets/NetworkAcceptor.h" -#include "tcpsockets/TCPStream.h" - -namespace wpi { - -class Logger; - -class TCPAcceptor : public NetworkAcceptor { - int m_lsd; - int m_port; - std::string m_address; - bool m_listening; - std::atomic_bool m_shutdown; - Logger& m_logger; - - public: - TCPAcceptor(int port, const char* address, Logger& logger); - ~TCPAcceptor(); - - int start() override; - void shutdown() override; - std::unique_ptr accept() override; -}; - -} // namespace wpi - -#endif // WPIUTIL_TCPSOCKETS_TCPACCEPTOR_H_ diff --git a/wpiutil/include/tcpsockets/TCPConnector.h b/wpiutil/include/tcpsockets/TCPConnector.h deleted file mode 100644 index 7afb044..0000000 --- a/wpiutil/include/tcpsockets/TCPConnector.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - TCPConnector.h - - TCPConnector class interface. TCPConnector provides methods to actively - establish TCP/IP connections with a server. - - ------------------------------------------ - - Copyright © 2013 [Vic Hargrave - http://vichargrave.com] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License -*/ - -#ifndef WPIUTIL_TCPSOCKETS_TCPCONNECTOR_H_ -#define WPIUTIL_TCPSOCKETS_TCPCONNECTOR_H_ - -#include - -#include "tcpsockets/NetworkStream.h" - -namespace wpi { - -class Logger; - -class TCPConnector { - public: - static std::unique_ptr connect(const char* server, int port, - Logger& logger, - int timeout = 0); -}; - -} // namespace wpi - -#endif // WPIUTIL_TCPSOCKETS_TCPCONNECTOR_H_ diff --git a/wpiutil/include/tcpsockets/TCPStream.h b/wpiutil/include/tcpsockets/TCPStream.h deleted file mode 100644 index 89e3779..0000000 --- a/wpiutil/include/tcpsockets/TCPStream.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - TCPStream.h - - TCPStream class interface. TCPStream provides methods to trasnfer - data between peers over a TCP/IP connection. - - ------------------------------------------ - - Copyright © 2013 [Vic Hargrave - http://vichargrave.com] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -#ifndef WPIUTIL_TCPSOCKETS_TCPSTREAM_H_ -#define WPIUTIL_TCPSOCKETS_TCPSTREAM_H_ - -#include -#include - -#ifdef _WIN32 -#include -#else -#include -#endif - -#include "tcpsockets/NetworkStream.h" - -struct sockaddr_in; - -namespace wpi { - -class TCPStream : public NetworkStream { - int m_sd; - std::string m_peerIP; - int m_peerPort; - bool m_blocking; - - public: - friend class TCPAcceptor; - friend class TCPConnector; - - ~TCPStream(); - - std::size_t send(const char* buffer, std::size_t len, Error* err) override; - std::size_t receive(char* buffer, std::size_t len, Error* err, - int timeout = 0) override; - void close() override; - - llvm::StringRef getPeerIP() const override; - int getPeerPort() const override; - void setNoDelay() override; - bool setBlocking(bool enabled) override; - int getNativeHandle() const override; - - TCPStream(const TCPStream& stream) = delete; - TCPStream& operator=(const TCPStream&) = delete; - private: - bool WaitForReadEvent(int timeout); - - TCPStream(int sd, sockaddr_in* address); - TCPStream() = delete; -}; - -} // namespace wpi - -#endif diff --git a/wpiutil/src/llvm/ConvertUTF.cpp b/wpiutil/src/llvm/ConvertUTF.cpp deleted file mode 100644 index 73f66d1..0000000 --- a/wpiutil/src/llvm/ConvertUTF.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/*===--- ConvertUTF.c - Universal Character Names conversions ---------------=== - * - * The LLVM Compiler Infrastructure - * - * This file is distributed under the University of Illinois Open Source - * License. See LICENSE.TXT for details. - * - *===------------------------------------------------------------------------=*/ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Source code file. - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Sept 2001: fixed const & error conditions per - mods suggested by S. Parent & A. Lillich. - June 2002: Tim Dodd added detection and handling of incomplete - source sequences, enhanced error detection, added casts - to eliminate compiler warnings. - July 2003: slight mods to back out aggressive FFFE detection. - Jan 2004: updated switches in from-UTF8 conversions. - Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. - - See the header file "ConvertUTF.h" for complete documentation. - ------------------------------------------------------------------------- */ - - -#include "llvm/ConvertUTF.h" -#ifdef CVTUTF_DEBUG -#include -#endif -#include - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF - -/* --------------------------------------------------------------------- */ - -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -/* - * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed - * into the first byte, depending on how many bytes follow. There are - * as many entries in this table as there are UTF-8 sequence types. - * (I.e., one byte sequence, two byte... etc.). Remember that sequencs - * for *legal* UTF-8 will be 4 or fewer bytes total. - */ -static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -/* --------------------------------------------------------------------- */ - -/* The interface converts a whole buffer to avoid function-call overhead. - * Constants have been gathered. Loops & conditionals have been removed as - * much as possible for efficiency, in favor of drop-through switches. - * (See "Note A" at the bottom of the file for equivalent code.) - * If your compiler supports it, the "isLegalUTF8" call can be turned - * into an inline function. - */ - -extern "C" { -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - if (target >= targetEnd) { - result = targetExhausted; break; - } - ch = *source++; - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_LEGAL_UTF32) { - if (flags == strictConversion) { - result = sourceIllegal; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - --source; /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF32* target = *targetStart; - UTF32 ch, ch2; - while (source < sourceEnd) { - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - if (target >= targetEnd) { - source = oldSource; /* Back up source pointer! */ - result = targetExhausted; break; - } - *target++ = ch; - } - *sourceStart = source; - *targetStart = target; -#ifdef CVTUTF_DEBUG -if (result == sourceIllegal) { - fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); - fflush(stderr); -} -#endif - return result; -} -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - UTF32 ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* Figure out how many bytes the result will require */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - } - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - ch = *source++; - if (flags == strictConversion ) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* - * Figure out how many bytes the result will require. Turn any - * illegally large UTF32 things (> Plane 17) into replacement chars. - */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - result = sourceIllegal; - } - - target += bytesToWrite; - if (target > targetEnd) { - --source; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns false. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ - -static Boolean isLegalUTF8(const UTF8 *source, int length) { - UTF8 a; - const UTF8 *srcptr = source+length; - switch (length) { - default: return false; - /* Everything else falls through when "true"... */ - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 2: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; - default: if (a < 0x80) return false; - } - - case 1: if (*source >= 0x80 && *source < 0xC2) return false; - } - if (*source > 0xF4) return false; - return true; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 sequence is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { - int length = trailingBytesForUTF8[*source]+1; - if (length > sourceEnd - source) { - return false; - } - return isLegalUTF8(source, length); -} - -/* --------------------------------------------------------------------- */ - -static unsigned -findMaximalSubpartOfIllFormedUTF8Sequence(const UTF8 *source, - const UTF8 *sourceEnd) { - UTF8 b1, b2, b3; - - assert(!isLegalUTF8Sequence(source, sourceEnd)); - - /* - * Unicode 6.3.0, D93b: - * - * Maximal subpart of an ill-formed subsequence: The longest code unit - * subsequence starting at an unconvertible offset that is either: - * a. the initial subsequence of a well-formed code unit sequence, or - * b. a subsequence of length one. - */ - - if (source == sourceEnd) - return 0; - - /* - * Perform case analysis. See Unicode 6.3.0, Table 3-7. Well-Formed UTF-8 - * Byte Sequences. - */ - - b1 = *source; - ++source; - if (b1 >= 0xC2 && b1 <= 0xDF) { - /* - * First byte is valid, but we know that this code unit sequence is - * invalid, so the maximal subpart has to end after the first byte. - */ - return 1; - } - - if (source == sourceEnd) - return 1; - - b2 = *source; - ++source; - - if (b1 == 0xE0) { - return (b2 >= 0xA0 && b2 <= 0xBF) ? 2 : 1; - } - if (b1 >= 0xE1 && b1 <= 0xEC) { - return (b2 >= 0x80 && b2 <= 0xBF) ? 2 : 1; - } - if (b1 == 0xED) { - return (b2 >= 0x80 && b2 <= 0x9F) ? 2 : 1; - } - if (b1 >= 0xEE && b1 <= 0xEF) { - return (b2 >= 0x80 && b2 <= 0xBF) ? 2 : 1; - } - if (b1 == 0xF0) { - if (b2 >= 0x90 && b2 <= 0xBF) { - if (source == sourceEnd) - return 2; - - b3 = *source; - return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2; - } - return 1; - } - if (b1 >= 0xF1 && b1 <= 0xF3) { - if (b2 >= 0x80 && b2 <= 0xBF) { - if (source == sourceEnd) - return 2; - - b3 = *source; - return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2; - } - return 1; - } - if (b1 == 0xF4) { - if (b2 >= 0x80 && b2 <= 0x8F) { - if (source == sourceEnd) - return 2; - - b3 = *source; - return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2; - } - return 1; - } - - assert((b1 >= 0x80 && b1 <= 0xC1) || b1 >= 0xF5); - /* - * There are no valid sequences that start with these bytes. Maximal subpart - * is defined to have length 1 in these cases. - */ - return 1; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return the total number of bytes in a codepoint - * represented in UTF-8, given the value of the first byte. - */ -unsigned getNumBytesForUTF8(UTF8 first) { - return trailingBytesForUTF8[first] + 1; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 string is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd) { - while (*source != sourceEnd) { - int length = trailingBytesForUTF8[**source] + 1; - if (length > sourceEnd - *source || !isLegalUTF8(*source, length)) - return false; - *source += length; - } - return true; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (extraBytesToRead >= sourceEnd - source) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (!isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_UTF16) { - if (flags == strictConversion) { - result = sourceIllegal; - source -= (extraBytesToRead+1); /* return to the start */ - break; /* Bail out; shouldn't continue */ - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -static ConversionResult ConvertUTF8toUTF32Impl( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags, - Boolean InputIsPartial) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF32* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (extraBytesToRead >= sourceEnd - source) { - if (flags == strictConversion || InputIsPartial) { - result = sourceExhausted; - break; - } else { - result = sourceIllegal; - - /* - * Replace the maximal subpart of ill-formed sequence with - * replacement character. - */ - source += findMaximalSubpartOfIllFormedUTF8Sequence(source, - sourceEnd); - *target++ = UNI_REPLACEMENT_CHAR; - continue; - } - } - if (target >= targetEnd) { - result = targetExhausted; break; - } - - /* Do this check whether lenient or strict */ - if (!isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - if (flags == strictConversion) { - /* Abort conversion. */ - break; - } else { - /* - * Replace the maximal subpart of ill-formed sequence with - * replacement character. - */ - source += findMaximalSubpartOfIllFormedUTF8Sequence(source, - sourceEnd); - *target++ = UNI_REPLACEMENT_CHAR; - continue; - } - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; - case 4: ch += *source++; ch <<= 6; - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (ch <= UNI_MAX_LEGAL_UTF32) { - /* - * UTF-16 surrogate values are illegal in UTF-32, and anything - * over Plane 17 (> 0x10FFFF) is illegal. - */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = ch; - } - } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ - result = sourceIllegal; - *target++ = UNI_REPLACEMENT_CHAR; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -ConversionResult ConvertUTF8toUTF32Partial(const UTF8 **sourceStart, - const UTF8 *sourceEnd, - UTF32 **targetStart, - UTF32 *targetEnd, - ConversionFlags flags) { - return ConvertUTF8toUTF32Impl(sourceStart, sourceEnd, targetStart, targetEnd, - flags, /*InputIsPartial=*/true); -} - -ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, - const UTF8 *sourceEnd, UTF32 **targetStart, - UTF32 *targetEnd, ConversionFlags flags) { - return ConvertUTF8toUTF32Impl(sourceStart, sourceEnd, targetStart, targetEnd, - flags, /*InputIsPartial=*/false); -} - -} - -/* --------------------------------------------------------------------- - - Note A. - The fall-through switches in UTF-8 reading code save a - temp variable, some decrements & conditionals. The switches - are equivalent to the following loop: - { - int tmpBytesToRead = extraBytesToRead+1; - do { - ch += *source++; - --tmpBytesToRead; - if (tmpBytesToRead) ch <<= 6; - } while (tmpBytesToRead > 0); - } - In UTF-8 writing code, the switches on "bytesToWrite" are - similarly unrolled loops. - - --------------------------------------------------------------------- */ diff --git a/wpiutil/src/llvm/ConvertUTFWrapper.cpp b/wpiutil/src/llvm/ConvertUTFWrapper.cpp deleted file mode 100644 index 810c135..0000000 --- a/wpiutil/src/llvm/ConvertUTFWrapper.cpp +++ /dev/null @@ -1,122 +0,0 @@ -//===-- ConvertUTFWrapper.cpp - Wrap ConvertUTF.h with clang data types -----=== -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ConvertUTF.h" -#include -#include - -namespace llvm { - -bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) { - const UTF32 *SourceStart = &Source; - const UTF32 *SourceEnd = SourceStart + 1; - UTF8 *TargetStart = reinterpret_cast(ResultPtr); - UTF8 *TargetEnd = TargetStart + 4; - ConversionResult CR = ConvertUTF32toUTF8(&SourceStart, SourceEnd, - &TargetStart, TargetEnd, - strictConversion); - if (CR != conversionOK) - return false; - - ResultPtr = reinterpret_cast(TargetStart); - return true; -} - -bool hasUTF16ByteOrderMark(ArrayRef S) { - return (S.size() >= 2 && - ((S[0] == '\xff' && S[1] == '\xfe') || - (S[0] == '\xfe' && S[1] == '\xff'))); -} - -bool convertUTF16ToUTF8String(ArrayRef SrcUTF16, - SmallVectorImpl &DstUTF8) { - assert(DstUTF8.empty()); - - // Avoid OOB by returning early on empty input. - if (SrcUTF16.empty()) - return true; - - const UTF16 *Src = SrcUTF16.begin(); - const UTF16 *SrcEnd = SrcUTF16.end(); - - // Byteswap if necessary. - std::vector ByteSwapped; - if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) { - ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd); - for (unsigned I = 0, E = ByteSwapped.size(); I != E; ++I) - ByteSwapped[I] = (ByteSwapped[I] << 8) | (ByteSwapped[I] >> 8); - Src = &ByteSwapped[0]; - SrcEnd = &ByteSwapped[ByteSwapped.size() - 1] + 1; - } - - // Skip the BOM for conversion. - if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_NATIVE) - Src++; - - // Just allocate enough space up front. We'll shrink it later. Allocate - // enough that we can fit a null terminator without reallocating. - DstUTF8.resize(SrcUTF16.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1); - UTF8 *Dst = reinterpret_cast(&DstUTF8[0]); - UTF8 *DstEnd = Dst + DstUTF8.size(); - - ConversionResult CR = - ConvertUTF16toUTF8(&Src, SrcEnd, &Dst, DstEnd, strictConversion); - assert(CR != targetExhausted); - - if (CR != conversionOK) { - DstUTF8.clear(); - return false; - } - - DstUTF8.resize(reinterpret_cast(Dst) - &DstUTF8[0]); - DstUTF8.push_back(0); - DstUTF8.pop_back(); - return true; -} - -bool convertUTF8ToUTF16String(StringRef SrcUTF8, - SmallVectorImpl &DstUTF16) { - assert(DstUTF16.empty()); - - // Avoid OOB by returning early on empty input. - if (SrcUTF8.empty()) { - DstUTF16.push_back(0); - DstUTF16.pop_back(); - return true; - } - - const UTF8 *Src = reinterpret_cast(SrcUTF8.begin()); - const UTF8 *SrcEnd = reinterpret_cast(SrcUTF8.end()); - - // Allocate the same number of UTF-16 code units as UTF-8 code units. Encoding - // as UTF-16 should always require the same amount or less code units than the - // UTF-8 encoding. Allocate one extra byte for the null terminator though, - // so that someone calling DstUTF16.data() gets a null terminated string. - // We resize down later so we don't have to worry that this over allocates. - DstUTF16.resize(SrcUTF8.size()+1); - UTF16 *Dst = &DstUTF16[0]; - UTF16 *DstEnd = Dst + DstUTF16.size(); - - ConversionResult CR = - ConvertUTF8toUTF16(&Src, SrcEnd, &Dst, DstEnd, strictConversion); - assert(CR != targetExhausted); - - if (CR != conversionOK) { - DstUTF16.clear(); - return false; - } - - DstUTF16.resize(Dst - &DstUTF16[0]); - DstUTF16.push_back(0); - DstUTF16.pop_back(); - return true; -} - -} // end namespace llvm - diff --git a/wpiutil/src/llvm/ErrorHandling.cpp b/wpiutil/src/llvm/ErrorHandling.cpp deleted file mode 100644 index 1ab2405..0000000 --- a/wpiutil/src/llvm/ErrorHandling.cpp +++ /dev/null @@ -1,83 +0,0 @@ -//===- lib/Support/ErrorHandling.cpp - Callbacks for errors ---------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines an API used to indicate fatal error conditions. Non-fatal -// errors (most of them) should be handled through LLVMContext. -// -//===----------------------------------------------------------------------===// - -#include "llvm/WindowsError.h" - -#ifdef _WIN32 - -#include -#include - -// I'd rather not double the line count of the following. -#define MAP_ERR_TO_COND(x, y) \ - case x: \ - return std::make_error_code(std::errc::y) - -std::error_code llvm::mapWindowsError(unsigned EV) { - switch (EV) { - MAP_ERR_TO_COND(ERROR_ACCESS_DENIED, permission_denied); - MAP_ERR_TO_COND(ERROR_ALREADY_EXISTS, file_exists); - MAP_ERR_TO_COND(ERROR_BAD_UNIT, no_such_device); - MAP_ERR_TO_COND(ERROR_BUFFER_OVERFLOW, filename_too_long); - MAP_ERR_TO_COND(ERROR_BUSY, device_or_resource_busy); - MAP_ERR_TO_COND(ERROR_BUSY_DRIVE, device_or_resource_busy); - MAP_ERR_TO_COND(ERROR_CANNOT_MAKE, permission_denied); - MAP_ERR_TO_COND(ERROR_CANTOPEN, io_error); - MAP_ERR_TO_COND(ERROR_CANTREAD, io_error); - MAP_ERR_TO_COND(ERROR_CANTWRITE, io_error); - MAP_ERR_TO_COND(ERROR_CURRENT_DIRECTORY, permission_denied); - MAP_ERR_TO_COND(ERROR_DEV_NOT_EXIST, no_such_device); - MAP_ERR_TO_COND(ERROR_DEVICE_IN_USE, device_or_resource_busy); - MAP_ERR_TO_COND(ERROR_DIR_NOT_EMPTY, directory_not_empty); - MAP_ERR_TO_COND(ERROR_DIRECTORY, invalid_argument); - MAP_ERR_TO_COND(ERROR_DISK_FULL, no_space_on_device); - MAP_ERR_TO_COND(ERROR_FILE_EXISTS, file_exists); - MAP_ERR_TO_COND(ERROR_FILE_NOT_FOUND, no_such_file_or_directory); - MAP_ERR_TO_COND(ERROR_HANDLE_DISK_FULL, no_space_on_device); - MAP_ERR_TO_COND(ERROR_INVALID_ACCESS, permission_denied); - MAP_ERR_TO_COND(ERROR_INVALID_DRIVE, no_such_device); - MAP_ERR_TO_COND(ERROR_INVALID_FUNCTION, function_not_supported); - MAP_ERR_TO_COND(ERROR_INVALID_HANDLE, invalid_argument); - MAP_ERR_TO_COND(ERROR_INVALID_NAME, invalid_argument); - MAP_ERR_TO_COND(ERROR_LOCK_VIOLATION, no_lock_available); - MAP_ERR_TO_COND(ERROR_LOCKED, no_lock_available); - MAP_ERR_TO_COND(ERROR_NEGATIVE_SEEK, invalid_argument); - MAP_ERR_TO_COND(ERROR_NOACCESS, permission_denied); - MAP_ERR_TO_COND(ERROR_NOT_ENOUGH_MEMORY, not_enough_memory); - MAP_ERR_TO_COND(ERROR_NOT_READY, resource_unavailable_try_again); - MAP_ERR_TO_COND(ERROR_OPEN_FAILED, io_error); - MAP_ERR_TO_COND(ERROR_OPEN_FILES, device_or_resource_busy); - MAP_ERR_TO_COND(ERROR_OUTOFMEMORY, not_enough_memory); - MAP_ERR_TO_COND(ERROR_PATH_NOT_FOUND, no_such_file_or_directory); - MAP_ERR_TO_COND(ERROR_BAD_NETPATH, no_such_file_or_directory); - MAP_ERR_TO_COND(ERROR_READ_FAULT, io_error); - MAP_ERR_TO_COND(ERROR_RETRY, resource_unavailable_try_again); - MAP_ERR_TO_COND(ERROR_SEEK, io_error); - MAP_ERR_TO_COND(ERROR_SHARING_VIOLATION, permission_denied); - MAP_ERR_TO_COND(ERROR_TOO_MANY_OPEN_FILES, too_many_files_open); - MAP_ERR_TO_COND(ERROR_WRITE_FAULT, io_error); - MAP_ERR_TO_COND(ERROR_WRITE_PROTECT, permission_denied); - MAP_ERR_TO_COND(WSAEACCES, permission_denied); - MAP_ERR_TO_COND(WSAEBADF, bad_file_descriptor); - MAP_ERR_TO_COND(WSAEFAULT, bad_address); - MAP_ERR_TO_COND(WSAEINTR, interrupted); - MAP_ERR_TO_COND(WSAEINVAL, invalid_argument); - MAP_ERR_TO_COND(WSAEMFILE, too_many_files_open); - MAP_ERR_TO_COND(WSAENAMETOOLONG, filename_too_long); - default: - return std::error_code(EV, std::system_category()); - } -} - -#endif diff --git a/wpiutil/src/llvm/Hashing.cpp b/wpiutil/src/llvm/Hashing.cpp deleted file mode 100644 index b280043..0000000 --- a/wpiutil/src/llvm/Hashing.cpp +++ /dev/null @@ -1,29 +0,0 @@ -//===-------------- lib/Support/Hashing.cpp -------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides implementation bits for the LLVM common hashing -// infrastructure. Documentation and most of the other information is in the -// header file. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Hashing.h" - -using namespace llvm; - -// Provide a definition and static initializer for the fixed seed. This -// initializer should always be zero to ensure its value can never appear to be -// non-zero, even during dynamic initialization. -size_t llvm::hashing::detail::fixed_seed_override = 0; - -// Implement the function for forced setting of the fixed seed. -// FIXME: Use atomic operations here so that there is no data race. -void llvm::set_fixed_execution_hash_seed(size_t fixed_value) { - hashing::detail::fixed_seed_override = fixed_value; -} diff --git a/wpiutil/src/llvm/SmallPtrSet.cpp b/wpiutil/src/llvm/SmallPtrSet.cpp deleted file mode 100644 index 6187f78..0000000 --- a/wpiutil/src/llvm/SmallPtrSet.cpp +++ /dev/null @@ -1,295 +0,0 @@ -//===- llvm/ADT/SmallPtrSet.cpp - 'Normally small' pointer set ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the SmallPtrSet class. See SmallPtrSet.h for an -// overview of the algorithm. -// -//===----------------------------------------------------------------------===// - -#include "llvm/SmallPtrSet.h" -#include "llvm/DenseMapInfo.h" -#include "llvm/MathExtras.h" -#include -#include - -using namespace llvm; - -void SmallPtrSetImplBase::shrink_and_clear() { - assert(!isSmall() && "Can't shrink a small set!"); - free(CurArray); - - // Reduce the number of buckets. - unsigned Size = size(); - CurArraySize = Size > 16 ? 1 << (Log2_32_Ceil(Size) + 1) : 32; - NumNonEmpty = NumTombstones = 0; - - // Install the new array. Clear all the buckets to empty. - CurArray = (const void**)malloc(sizeof(void*) * CurArraySize); - assert(CurArray && "Failed to allocate memory?"); - memset(CurArray, -1, CurArraySize*sizeof(void*)); -} - -std::pair -SmallPtrSetImplBase::insert_imp_big(const void *Ptr) { - if (LLVM_UNLIKELY(size() * 4 >= CurArraySize * 3)) { - // If more than 3/4 of the array is full, grow. - Grow(CurArraySize < 64 ? 128 : CurArraySize * 2); - } else if (LLVM_UNLIKELY(CurArraySize - NumNonEmpty < CurArraySize / 8)) { - // If fewer of 1/8 of the array is empty (meaning that many are filled with - // tombstones), rehash. - Grow(CurArraySize); - } - - // Okay, we know we have space. Find a hash bucket. - const void **Bucket = const_cast(FindBucketFor(Ptr)); - if (*Bucket == Ptr) - return std::make_pair(Bucket, false); // Already inserted, good. - - // Otherwise, insert it! - if (*Bucket == getTombstoneMarker()) - --NumTombstones; - else - ++NumNonEmpty; // Track density. - *Bucket = Ptr; - return std::make_pair(Bucket, true); -} - -bool SmallPtrSetImplBase::erase_imp(const void * Ptr) { - if (isSmall()) { - // Check to see if it is in the set. - for (const void **APtr = CurArray, **E = CurArray + NumNonEmpty; APtr != E; - ++APtr) - if (*APtr == Ptr) { - // If it is in the set, replace this element. - *APtr = getTombstoneMarker(); - ++NumTombstones; - return true; - } - - return false; - } - - // Okay, we know we have space. Find a hash bucket. - void **Bucket = const_cast(FindBucketFor(Ptr)); - if (*Bucket != Ptr) return false; // Not in the set? - - // Set this as a tombstone. - *Bucket = getTombstoneMarker(); - ++NumTombstones; - return true; -} - -const void * const *SmallPtrSetImplBase::FindBucketFor(const void *Ptr) const { - unsigned Bucket = DenseMapInfo::getHashValue(Ptr) & (CurArraySize-1); - unsigned ArraySize = CurArraySize; - unsigned ProbeAmt = 1; - const void *const *Array = CurArray; - const void *const *Tombstone = nullptr; - while (1) { - // If we found an empty bucket, the pointer doesn't exist in the set. - // Return a tombstone if we've seen one so far, or the empty bucket if - // not. - if (LLVM_LIKELY(Array[Bucket] == getEmptyMarker())) - return Tombstone ? Tombstone : Array+Bucket; - - // Found Ptr's bucket? - if (LLVM_LIKELY(Array[Bucket] == Ptr)) - return Array+Bucket; - - // If this is a tombstone, remember it. If Ptr ends up not in the set, we - // prefer to return it than something that would require more probing. - if (Array[Bucket] == getTombstoneMarker() && !Tombstone) - Tombstone = Array+Bucket; // Remember the first tombstone found. - - // It's a hash collision or a tombstone. Reprobe. - Bucket = (Bucket + ProbeAmt++) & (ArraySize-1); - } -} - -/// Grow - Allocate a larger backing store for the buckets and move it over. -/// -void SmallPtrSetImplBase::Grow(unsigned NewSize) { - const void **OldBuckets = CurArray; - const void **OldEnd = EndPointer(); - bool WasSmall = isSmall(); - - // Install the new array. Clear all the buckets to empty. - CurArray = (const void**)malloc(sizeof(void*) * NewSize); - assert(CurArray && "Failed to allocate memory?"); - CurArraySize = NewSize; - memset(CurArray, -1, NewSize*sizeof(void*)); - - // Copy over all valid entries. - for (const void **BucketPtr = OldBuckets; BucketPtr != OldEnd; ++BucketPtr) { - // Copy over the element if it is valid. - const void *Elt = *BucketPtr; - if (Elt != getTombstoneMarker() && Elt != getEmptyMarker()) - *const_cast(FindBucketFor(Elt)) = const_cast(Elt); - } - - if (!WasSmall) - free(OldBuckets); - NumNonEmpty -= NumTombstones; - NumTombstones = 0; -} - -SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage, - const SmallPtrSetImplBase &that) { - SmallArray = SmallStorage; - - // If we're becoming small, prepare to insert into our stack space - if (that.isSmall()) { - CurArray = SmallArray; - // Otherwise, allocate new heap space (unless we were the same size) - } else { - CurArray = (const void**)malloc(sizeof(void*) * that.CurArraySize); - assert(CurArray && "Failed to allocate memory?"); - } - - // Copy over the that array. - CopyHelper(that); -} - -SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage, - unsigned SmallSize, - SmallPtrSetImplBase &&that) { - SmallArray = SmallStorage; - MoveHelper(SmallSize, std::move(that)); -} - -void SmallPtrSetImplBase::CopyFrom(const SmallPtrSetImplBase &RHS) { - assert(&RHS != this && "Self-copy should be handled by the caller."); - - if (isSmall() && RHS.isSmall()) - assert(CurArraySize == RHS.CurArraySize && - "Cannot assign sets with different small sizes"); - - // If we're becoming small, prepare to insert into our stack space - if (RHS.isSmall()) { - if (!isSmall()) - free(CurArray); - CurArray = SmallArray; - // Otherwise, allocate new heap space (unless we were the same size) - } else if (CurArraySize != RHS.CurArraySize) { - if (isSmall()) - CurArray = (const void**)malloc(sizeof(void*) * RHS.CurArraySize); - else { - const void **T = (const void**)realloc(CurArray, - sizeof(void*) * RHS.CurArraySize); - if (!T) - free(CurArray); - CurArray = T; - } - assert(CurArray && "Failed to allocate memory?"); - } - - CopyHelper(RHS); -} - -void SmallPtrSetImplBase::CopyHelper(const SmallPtrSetImplBase &RHS) { - // Copy over the new array size - CurArraySize = RHS.CurArraySize; - - // Copy over the contents from the other set - std::copy(RHS.CurArray, RHS.EndPointer(), CurArray); - - NumNonEmpty = RHS.NumNonEmpty; - NumTombstones = RHS.NumTombstones; -} - -void SmallPtrSetImplBase::MoveFrom(unsigned SmallSize, - SmallPtrSetImplBase &&RHS) { - if (!isSmall()) - free(CurArray); - MoveHelper(SmallSize, std::move(RHS)); -} - -void SmallPtrSetImplBase::MoveHelper(unsigned SmallSize, - SmallPtrSetImplBase &&RHS) { - assert(&RHS != this && "Self-move should be handled by the caller."); - - if (RHS.isSmall()) { - // Copy a small RHS rather than moving. - CurArray = SmallArray; - std::copy(RHS.CurArray, RHS.CurArray + RHS.NumNonEmpty, CurArray); - } else { - CurArray = RHS.CurArray; - RHS.CurArray = RHS.SmallArray; - } - - // Copy the rest of the trivial members. - CurArraySize = RHS.CurArraySize; - NumNonEmpty = RHS.NumNonEmpty; - NumTombstones = RHS.NumTombstones; - - // Make the RHS small and empty. - RHS.CurArraySize = SmallSize; - assert(RHS.CurArray == RHS.SmallArray); - RHS.NumNonEmpty = 0; - RHS.NumTombstones = 0; -} - -void SmallPtrSetImplBase::swap(SmallPtrSetImplBase &RHS) { - if (this == &RHS) return; - - // We can only avoid copying elements if neither set is small. - if (!this->isSmall() && !RHS.isSmall()) { - std::swap(this->CurArray, RHS.CurArray); - std::swap(this->CurArraySize, RHS.CurArraySize); - std::swap(this->NumNonEmpty, RHS.NumNonEmpty); - std::swap(this->NumTombstones, RHS.NumTombstones); - return; - } - - // FIXME: From here on we assume that both sets have the same small size. - - // If only RHS is small, copy the small elements into LHS and move the pointer - // from LHS to RHS. - if (!this->isSmall() && RHS.isSmall()) { - assert(RHS.CurArray == RHS.SmallArray); - std::copy(RHS.CurArray, RHS.CurArray + RHS.NumNonEmpty, this->SmallArray); - std::swap(RHS.CurArraySize, this->CurArraySize); - std::swap(this->NumNonEmpty, RHS.NumNonEmpty); - std::swap(this->NumTombstones, RHS.NumTombstones); - RHS.CurArray = this->CurArray; - this->CurArray = this->SmallArray; - return; - } - - // If only LHS is small, copy the small elements into RHS and move the pointer - // from RHS to LHS. - if (this->isSmall() && !RHS.isSmall()) { - assert(this->CurArray == this->SmallArray); - std::copy(this->CurArray, this->CurArray + this->NumNonEmpty, - RHS.SmallArray); - std::swap(RHS.CurArraySize, this->CurArraySize); - std::swap(RHS.NumNonEmpty, this->NumNonEmpty); - std::swap(RHS.NumTombstones, this->NumTombstones); - this->CurArray = RHS.CurArray; - RHS.CurArray = RHS.SmallArray; - return; - } - - // Both a small, just swap the small elements. - assert(this->isSmall() && RHS.isSmall()); - unsigned MinNonEmpty = std::min(this->NumNonEmpty, RHS.NumNonEmpty); - std::swap_ranges(this->SmallArray, this->SmallArray + MinNonEmpty, - RHS.SmallArray); - if (this->NumNonEmpty > MinNonEmpty) { - std::copy(this->SmallArray + MinNonEmpty, - this->SmallArray + this->NumNonEmpty, - RHS.SmallArray + MinNonEmpty); - } else { - std::copy(RHS.SmallArray + MinNonEmpty, RHS.SmallArray + RHS.NumNonEmpty, - this->SmallArray + MinNonEmpty); - } - assert(this->CurArraySize == RHS.CurArraySize); - std::swap(this->NumNonEmpty, RHS.NumNonEmpty); - std::swap(this->NumTombstones, RHS.NumTombstones); -} diff --git a/wpiutil/src/llvm/SmallVector.cpp b/wpiutil/src/llvm/SmallVector.cpp deleted file mode 100644 index 6aa709e..0000000 --- a/wpiutil/src/llvm/SmallVector.cpp +++ /dev/null @@ -1,41 +0,0 @@ -//===- llvm/ADT/SmallVector.cpp - 'Normally small' vectors ----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the SmallVector class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/SmallVector.h" -using namespace llvm; - -/// grow_pod - This is an implementation of the grow() method which only works -/// on POD-like datatypes and is out of line to reduce code duplication. -void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSizeInBytes, - size_t TSize) { - size_t CurSizeBytes = size_in_bytes(); - size_t NewCapacityInBytes = 2 * capacity_in_bytes() + TSize; // Always grow. - if (NewCapacityInBytes < MinSizeInBytes) - NewCapacityInBytes = MinSizeInBytes; - - void *NewElts; - if (BeginX == FirstEl) { - NewElts = malloc(NewCapacityInBytes); - - // Copy the elements over. No need to run dtors on PODs. - memcpy(NewElts, this->BeginX, CurSizeBytes); - } else { - // If this wasn't grown from the inline copy, grow the allocated space. - NewElts = realloc(this->BeginX, NewCapacityInBytes); - } - assert(NewElts && "Out of memory"); - - this->EndX = (char*)NewElts+CurSizeBytes; - this->BeginX = NewElts; - this->CapacityX = (char*)this->BeginX + NewCapacityInBytes; -} diff --git a/wpiutil/src/llvm/StringExtras.cpp b/wpiutil/src/llvm/StringExtras.cpp deleted file mode 100644 index 74b47a5..0000000 --- a/wpiutil/src/llvm/StringExtras.cpp +++ /dev/null @@ -1,58 +0,0 @@ -//===-- StringExtras.cpp - Implement the StringExtras header --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the StringExtras.h header -// -//===----------------------------------------------------------------------===// - -#include "llvm/StringExtras.h" -#include "llvm/SmallVector.h" -using namespace llvm; - -/// StrInStrNoCase - Portable version of strcasestr. Locates the first -/// occurrence of string 's1' in string 's2', ignoring case. Returns -/// the offset of s2 in s1 or npos if s2 cannot be found. -StringRef::size_type llvm::StrInStrNoCase(StringRef s1, StringRef s2) { - size_t N = s2.size(), M = s1.size(); - if (N > M) - return StringRef::npos; - for (size_t i = 0, e = M - N + 1; i != e; ++i) - if (s1.substr(i, N).equals_lower(s2)) - return i; - return StringRef::npos; -} - -/// getToken - This function extracts one token from source, ignoring any -/// leading characters that appear in the Delimiters string, and ending the -/// token at any of the characters that appear in the Delimiters string. If -/// there are no tokens in the source string, an empty string is returned. -/// The function returns a pair containing the extracted token and the -/// remaining tail string. -std::pair llvm::getToken(StringRef Source, - StringRef Delimiters) { - // Figure out where the token starts. - StringRef::size_type Start = Source.find_first_not_of(Delimiters); - - // Find the next occurrence of the delimiter. - StringRef::size_type End = Source.find_first_of(Delimiters, Start); - - return std::make_pair(Source.slice(Start, End), Source.substr(End)); -} - -/// SplitString - Split up the specified string according to the specified -/// delimiters, appending the result fragments to the output list. -void llvm::SplitString(StringRef Source, - SmallVectorImpl &OutFragments, - StringRef Delimiters) { - std::pair S = getToken(Source, Delimiters); - while (!S.first.empty()) { - OutFragments.push_back(S.first); - S = getToken(S.second, Delimiters); - } -} diff --git a/wpiutil/src/llvm/StringMap.cpp b/wpiutil/src/llvm/StringMap.cpp deleted file mode 100644 index 032c368..0000000 --- a/wpiutil/src/llvm/StringMap.cpp +++ /dev/null @@ -1,260 +0,0 @@ -//===--- StringMap.cpp - String Hash table map implementation -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the StringMap class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/StringMap.h" -#include "llvm/MathExtras.h" -#include "llvm/StringExtras.h" -#include "llvm/Compiler.h" -#include -using namespace llvm; - -/// Returns the number of buckets to allocate to ensure that the DenseMap can -/// accommodate \p NumEntries without need to grow(). -static unsigned getMinBucketToReserveForEntries(unsigned NumEntries) { - // Ensure that "NumEntries * 4 < NumBuckets * 3" - if (NumEntries == 0) - return 0; - // +1 is required because of the strict equality. - // For example if NumEntries is 48, we need to return 401. - return NextPowerOf2(NumEntries * 4 / 3 + 1); -} - -StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) { - ItemSize = itemSize; - - // If a size is specified, initialize the table with that many buckets. - if (InitSize) { - // The table will grow when the number of entries reach 3/4 of the number of - // buckets. To guarantee that "InitSize" number of entries can be inserted - // in the table without growing, we allocate just what is needed here. - init(getMinBucketToReserveForEntries(InitSize)); - return; - } - - // Otherwise, initialize it with zero buckets to avoid the allocation. - TheTable = nullptr; - NumBuckets = 0; - NumItems = 0; - NumTombstones = 0; -} - -void StringMapImpl::init(unsigned InitSize) { - assert((InitSize & (InitSize-1)) == 0 && - "Init Size must be a power of 2 or zero!"); - NumBuckets = InitSize ? InitSize : 16; - NumItems = 0; - NumTombstones = 0; - - TheTable = (StringMapEntryBase **)calloc(NumBuckets+1, - sizeof(StringMapEntryBase **) + - sizeof(unsigned)); - - // Allocate one extra bucket, set it to look filled so the iterators stop at - // end. - TheTable[NumBuckets] = (StringMapEntryBase*)2; -} - - -/// LookupBucketFor - Look up the bucket that the specified string should end -/// up in. If it already exists as a key in the map, the Item pointer for the -/// specified bucket will be non-null. Otherwise, it will be null. In either -/// case, the FullHashValue field of the bucket will be set to the hash value -/// of the string. -unsigned StringMapImpl::LookupBucketFor(StringRef Name) { - unsigned HTSize = NumBuckets; - if (HTSize == 0) { // Hash table unallocated so far? - init(16); - HTSize = NumBuckets; - } - unsigned FullHashValue = HashString(Name); - unsigned BucketNo = FullHashValue & (HTSize-1); - unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1); - - unsigned ProbeAmt = 1; - int FirstTombstone = -1; - while (1) { - StringMapEntryBase *BucketItem = TheTable[BucketNo]; - // If we found an empty bucket, this key isn't in the table yet, return it. - if (LLVM_LIKELY(!BucketItem)) { - // If we found a tombstone, we want to reuse the tombstone instead of an - // empty bucket. This reduces probing. - if (FirstTombstone != -1) { - HashTable[FirstTombstone] = FullHashValue; - return FirstTombstone; - } - - HashTable[BucketNo] = FullHashValue; - return BucketNo; - } - - if (BucketItem == getTombstoneVal()) { - // Skip over tombstones. However, remember the first one we see. - if (FirstTombstone == -1) FirstTombstone = BucketNo; - } else if (LLVM_LIKELY(HashTable[BucketNo] == FullHashValue)) { - // If the full hash value matches, check deeply for a match. The common - // case here is that we are only looking at the buckets (for item info - // being non-null and for the full hash value) not at the items. This - // is important for cache locality. - - // Do the comparison like this because Name isn't necessarily - // null-terminated! - char *ItemStr = (char*)BucketItem+ItemSize; - if (Name == StringRef(ItemStr, BucketItem->getKeyLength())) { - // We found a match! - return BucketNo; - } - } - - // Okay, we didn't find the item. Probe to the next bucket. - BucketNo = (BucketNo+ProbeAmt) & (HTSize-1); - - // Use quadratic probing, it has fewer clumping artifacts than linear - // probing and has good cache behavior in the common case. - ++ProbeAmt; - } -} - - -/// FindKey - Look up the bucket that contains the specified key. If it exists -/// in the map, return the bucket number of the key. Otherwise return -1. -/// This does not modify the map. -int StringMapImpl::FindKey(StringRef Key) const { - unsigned HTSize = NumBuckets; - if (HTSize == 0) return -1; // Really empty table? - unsigned FullHashValue = HashString(Key); - unsigned BucketNo = FullHashValue & (HTSize-1); - unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1); - - unsigned ProbeAmt = 1; - while (1) { - StringMapEntryBase *BucketItem = TheTable[BucketNo]; - // If we found an empty bucket, this key isn't in the table yet, return. - if (LLVM_LIKELY(!BucketItem)) - return -1; - - if (BucketItem == getTombstoneVal()) { - // Ignore tombstones. - } else if (LLVM_LIKELY(HashTable[BucketNo] == FullHashValue)) { - // If the full hash value matches, check deeply for a match. The common - // case here is that we are only looking at the buckets (for item info - // being non-null and for the full hash value) not at the items. This - // is important for cache locality. - - // Do the comparison like this because NameStart isn't necessarily - // null-terminated! - char *ItemStr = (char*)BucketItem+ItemSize; - if (Key == StringRef(ItemStr, BucketItem->getKeyLength())) { - // We found a match! - return BucketNo; - } - } - - // Okay, we didn't find the item. Probe to the next bucket. - BucketNo = (BucketNo+ProbeAmt) & (HTSize-1); - - // Use quadratic probing, it has fewer clumping artifacts than linear - // probing and has good cache behavior in the common case. - ++ProbeAmt; - } -} - -/// RemoveKey - Remove the specified StringMapEntry from the table, but do not -/// delete it. This aborts if the value isn't in the table. -void StringMapImpl::RemoveKey(StringMapEntryBase *V) { - const char *VStr = (char*)V + ItemSize; - StringMapEntryBase *V2 = RemoveKey(StringRef(VStr, V->getKeyLength())); - (void)V2; - assert(V == V2 && "Didn't find key?"); -} - -/// RemoveKey - Remove the StringMapEntry for the specified key from the -/// table, returning it. If the key is not in the table, this returns null. -StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) { - int Bucket = FindKey(Key); - if (Bucket == -1) return nullptr; - - StringMapEntryBase *Result = TheTable[Bucket]; - TheTable[Bucket] = getTombstoneVal(); - --NumItems; - ++NumTombstones; - assert(NumItems + NumTombstones <= NumBuckets); - - return Result; -} - - - -/// RehashTable - Grow the table, redistributing values into the buckets with -/// the appropriate mod-of-hashtable-size. -unsigned StringMapImpl::RehashTable(unsigned BucketNo) { - unsigned NewSize; - unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1); - - // If the hash table is now more than 3/4 full, or if fewer than 1/8 of - // the buckets are empty (meaning that many are filled with tombstones), - // grow/rehash the table. - if (LLVM_UNLIKELY(NumItems * 4 > NumBuckets * 3)) { - NewSize = NumBuckets*2; - } else if (LLVM_UNLIKELY(NumBuckets - (NumItems + NumTombstones) <= - NumBuckets / 8)) { - NewSize = NumBuckets; - } else { - return BucketNo; - } - - unsigned NewBucketNo = BucketNo; - // Allocate one extra bucket which will always be non-empty. This allows the - // iterators to stop at end. - StringMapEntryBase **NewTableArray = - (StringMapEntryBase **)calloc(NewSize+1, sizeof(StringMapEntryBase *) + - sizeof(unsigned)); - unsigned *NewHashArray = (unsigned *)(NewTableArray + NewSize + 1); - NewTableArray[NewSize] = (StringMapEntryBase*)2; - - // Rehash all the items into their new buckets. Luckily :) we already have - // the hash values available, so we don't have to rehash any strings. - for (unsigned I = 0, E = NumBuckets; I != E; ++I) { - StringMapEntryBase *Bucket = TheTable[I]; - if (Bucket && Bucket != getTombstoneVal()) { - // Fast case, bucket available. - unsigned FullHash = HashTable[I]; - unsigned NewBucket = FullHash & (NewSize-1); - if (!NewTableArray[NewBucket]) { - NewTableArray[FullHash & (NewSize-1)] = Bucket; - NewHashArray[FullHash & (NewSize-1)] = FullHash; - if (I == BucketNo) - NewBucketNo = NewBucket; - continue; - } - - // Otherwise probe for a spot. - unsigned ProbeSize = 1; - do { - NewBucket = (NewBucket + ProbeSize++) & (NewSize-1); - } while (NewTableArray[NewBucket]); - - // Finally found a slot. Fill it in. - NewTableArray[NewBucket] = Bucket; - NewHashArray[NewBucket] = FullHash; - if (I == BucketNo) - NewBucketNo = NewBucket; - } - } - - free(TheTable); - - TheTable = NewTableArray; - NumBuckets = NewSize; - NumTombstones = 0; - return NewBucketNo; -} diff --git a/wpiutil/src/llvm/StringRef.cpp b/wpiutil/src/llvm/StringRef.cpp deleted file mode 100644 index c254ae3..0000000 --- a/wpiutil/src/llvm/StringRef.cpp +++ /dev/null @@ -1,452 +0,0 @@ -//===-- StringRef.cpp - Lightweight String References ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/StringRef.h" -#include "llvm/Hashing.h" -#include "llvm/SmallVector.h" -#include -#include - -using namespace llvm; - -// MSVC emits references to this into the translation units which reference it. -#ifndef _MSC_VER -const size_t StringRef::npos; -#endif - -static char ascii_tolower(char x) { - if (x >= 'A' && x <= 'Z') - return x - 'A' + 'a'; - return x; -} - -static char ascii_toupper(char x) { - if (x >= 'a' && x <= 'z') - return x - 'a' + 'A'; - return x; -} - -static bool ascii_isdigit(char x) { - return x >= '0' && x <= '9'; -} - -// strncasecmp() is not available on non-POSIX systems, so define an -// alternative function here. -static int ascii_strncasecmp(const char *LHS, const char *RHS, size_t Length) { - for (size_t I = 0; I < Length; ++I) { - unsigned char LHC = ascii_tolower(LHS[I]); - unsigned char RHC = ascii_tolower(RHS[I]); - if (LHC != RHC) - return LHC < RHC ? -1 : 1; - } - return 0; -} - -/// compare_lower - Compare strings, ignoring case. -int StringRef::compare_lower(StringRef RHS) const { - if (int Res = ascii_strncasecmp(Data, RHS.Data, std::min(size(), RHS.size()))) - return Res; - if (size() == RHS.size()) - return 0; - return size() < RHS.size() ? -1 : 1; -} - -/// Check if this string starts with the given \p Prefix, ignoring case. -bool StringRef::startswith_lower(StringRef Prefix) const { - return size() >= Prefix.size() && - ascii_strncasecmp(Data, Prefix.Data, Prefix.size()) == 0; -} - -/// Check if this string ends with the given \p Suffix, ignoring case. -bool StringRef::endswith_lower(StringRef Suffix) const { - return size() >= Suffix.size() && - ascii_strncasecmp(end() - Suffix.size(), Suffix.Data, Suffix.size()) == 0; -} - -/// compare_numeric - Compare strings, handle embedded numbers. -int StringRef::compare_numeric(StringRef RHS) const { - for (size_t I = 0, E = std::min(size(), RHS.size()); I != E; ++I) { - // Check for sequences of digits. - if (ascii_isdigit(Data[I]) && ascii_isdigit(RHS.Data[I])) { - // The longer sequence of numbers is considered larger. - // This doesn't really handle prefixed zeros well. - size_t J; - for (J = I + 1; J != E + 1; ++J) { - bool ld = J < size() && ascii_isdigit(Data[J]); - bool rd = J < RHS.size() && ascii_isdigit(RHS.Data[J]); - if (ld != rd) - return rd ? -1 : 1; - if (!rd) - break; - } - // The two number sequences have the same length (J-I), just memcmp them. - if (int Res = compareMemory(Data + I, RHS.Data + I, J - I)) - return Res < 0 ? -1 : 1; - // Identical number sequences, continue search after the numbers. - I = J - 1; - continue; - } - if (Data[I] != RHS.Data[I]) - return (unsigned char)Data[I] < (unsigned char)RHS.Data[I] ? -1 : 1; - } - if (size() == RHS.size()) - return 0; - return size() < RHS.size() ? -1 : 1; -} - -//===----------------------------------------------------------------------===// -// String Operations -//===----------------------------------------------------------------------===// - -std::string StringRef::lower() const { - std::string Result(size(), char()); - for (size_type i = 0, e = size(); i != e; ++i) { - Result[i] = ascii_tolower(Data[i]); - } - return Result; -} - -std::string StringRef::upper() const { - std::string Result(size(), char()); - for (size_type i = 0, e = size(); i != e; ++i) { - Result[i] = ascii_toupper(Data[i]); - } - return Result; -} - -const char *StringRef::c_str(llvm::SmallVectorImpl& buf) const { - if (is_null_terminated()) { - // If null terminated, return data directly - return data(); - } else { - // If not null terminated, use SmallVectorImpl to store data - // copy data, and return a known null terminated string - buf.clear(); - buf.append(begin(), end()); - buf.push_back(0); - return buf.begin(); - } -} - -//===----------------------------------------------------------------------===// -// String Searching -//===----------------------------------------------------------------------===// - - -/// find - Search for the first string \arg Str in the string. -/// -/// \return - The index of the first occurrence of \arg Str, or npos if not -/// found. -size_t StringRef::find(StringRef Str, size_t From) const { - if (From > size()) - return npos; - - const char *Needle = Str.data(); - size_t N = Str.size(); - if (N == 0) - return From; - - size_t Size = size() - From; - if (Size < N) - return npos; - - const char *Start = Data + From; - const char *Stop = Start + (Size - N + 1); - - // For short haystacks or unsupported needles fall back to the naive algorithm - if (Size < 16 || N > 255) { - do { - if (std::memcmp(Start, Needle, N) == 0) - return Start - Data; - ++Start; - } while (Start < Stop); - return npos; - } - - // Build the bad char heuristic table, with uint8_t to reduce cache thrashing. - uint8_t BadCharSkip[256]; - std::memset(BadCharSkip, N, 256); - for (unsigned i = 0; i != N-1; ++i) - BadCharSkip[(uint8_t)Str[i]] = N-1-i; - - do { - if (std::memcmp(Start, Needle, N) == 0) - return Start - Data; - - // Otherwise skip the appropriate number of bytes. - Start += BadCharSkip[(uint8_t)Start[N-1]]; - } while (Start < Stop); - - return npos; -} - -/// rfind - Search for the last string \arg Str in the string. -/// -/// \return - The index of the last occurrence of \arg Str, or npos if not -/// found. -size_t StringRef::rfind(StringRef Str) const { - size_t N = Str.size(); - if (N > size()) - return npos; - for (size_t i = size() - N + 1, e = 0; i != e;) { - --i; - if (substr(i, N).equals(Str)) - return i; - } - return npos; -} - -/// find_first_of - Find the first character in the string that is in \arg -/// Chars, or npos if not found. -/// -/// Note: O(size() + Chars.size()) -StringRef::size_type StringRef::find_first_of(StringRef Chars, - size_t From) const { - std::bitset<1 << CHAR_BIT> CharBits; - for (size_type i = 0; i != Chars.size(); ++i) - CharBits.set((unsigned char)Chars[i]); - - for (size_type i = std::min(From, size()), e = size(); i != e; ++i) - if (CharBits.test((unsigned char)Data[i])) - return i; - return npos; -} - -/// find_first_not_of - Find the first character in the string that is not -/// \arg C or npos if not found. -StringRef::size_type StringRef::find_first_not_of(char C, size_t From) const { - for (size_type i = std::min(From, size()), e = size(); i != e; ++i) - if (Data[i] != C) - return i; - return npos; -} - -/// find_first_not_of - Find the first character in the string that is not -/// in the string \arg Chars, or npos if not found. -/// -/// Note: O(size() + Chars.size()) -StringRef::size_type StringRef::find_first_not_of(StringRef Chars, - size_t From) const { - std::bitset<1 << CHAR_BIT> CharBits; - for (size_type i = 0; i != Chars.size(); ++i) - CharBits.set((unsigned char)Chars[i]); - - for (size_type i = std::min(From, size()), e = size(); i != e; ++i) - if (!CharBits.test((unsigned char)Data[i])) - return i; - return npos; -} - -/// find_last_of - Find the last character in the string that is in \arg C, -/// or npos if not found. -/// -/// Note: O(size() + Chars.size()) -StringRef::size_type StringRef::find_last_of(StringRef Chars, - size_t From) const { - std::bitset<1 << CHAR_BIT> CharBits; - for (size_type i = 0; i != Chars.size(); ++i) - CharBits.set((unsigned char)Chars[i]); - - for (size_type i = std::min(From, size()) - 1, e = -1; i != e; --i) - if (CharBits.test((unsigned char)Data[i])) - return i; - return npos; -} - -/// find_last_not_of - Find the last character in the string that is not -/// \arg C, or npos if not found. -StringRef::size_type StringRef::find_last_not_of(char C, size_t From) const { - for (size_type i = std::min(From, size()) - 1, e = -1; i != e; --i) - if (Data[i] != C) - return i; - return npos; -} - -/// find_last_not_of - Find the last character in the string that is not in -/// \arg Chars, or npos if not found. -/// -/// Note: O(size() + Chars.size()) -StringRef::size_type StringRef::find_last_not_of(StringRef Chars, - size_t From) const { - std::bitset<1 << CHAR_BIT> CharBits; - for (size_type i = 0, e = Chars.size(); i != e; ++i) - CharBits.set((unsigned char)Chars[i]); - - for (size_type i = std::min(From, size()) - 1, e = -1; i != e; --i) - if (!CharBits.test((unsigned char)Data[i])) - return i; - return npos; -} - -void StringRef::split(SmallVectorImpl &A, - StringRef Separator, int MaxSplit, - bool KeepEmpty) const { - StringRef S = *this; - - // Count down from MaxSplit. When MaxSplit is -1, this will just split - // "forever". This doesn't support splitting more than 2^31 times - // intentionally; if we ever want that we can make MaxSplit a 64-bit integer - // but that seems unlikely to be useful. - while (MaxSplit-- != 0) { - size_t Idx = S.find(Separator); - if (Idx == npos) - break; - - // Push this split. - if (KeepEmpty || Idx > 0) - A.push_back(S.slice(0, Idx)); - - // Jump forward. - S = S.slice(Idx + Separator.size(), npos); - } - - // Push the tail. - if (KeepEmpty || !S.empty()) - A.push_back(S); -} - -void StringRef::split(SmallVectorImpl &A, char Separator, - int MaxSplit, bool KeepEmpty) const { - StringRef S = *this; - - // Count down from MaxSplit. When MaxSplit is -1, this will just split - // "forever". This doesn't support splitting more than 2^31 times - // intentionally; if we ever want that we can make MaxSplit a 64-bit integer - // but that seems unlikely to be useful. - while (MaxSplit-- != 0) { - size_t Idx = S.find(Separator); - if (Idx == npos) - break; - - // Push this split. - if (KeepEmpty || Idx > 0) - A.push_back(S.slice(0, Idx)); - - // Jump forward. - S = S.slice(Idx + 1, npos); - } - - // Push the tail. - if (KeepEmpty || !S.empty()) - A.push_back(S); -} - -//===----------------------------------------------------------------------===// -// Helpful Algorithms -//===----------------------------------------------------------------------===// - -/// count - Return the number of non-overlapped occurrences of \arg Str in -/// the string. -size_t StringRef::count(StringRef Str) const { - size_t Count = 0; - size_t N = Str.size(); - if (N > size()) - return 0; - for (size_t i = 0, e = size() - N + 1; i != e; ++i) - if (substr(i, N).equals(Str)) - ++Count; - return Count; -} - -static unsigned GetAutoSenseRadix(StringRef &Str) { - if (Str.startswith("0x") || Str.startswith("0X")) { - Str = Str.substr(2); - return 16; - } - - if (Str.startswith("0b") || Str.startswith("0B")) { - Str = Str.substr(2); - return 2; - } - - if (Str.startswith("0o")) { - Str = Str.substr(2); - return 8; - } - - if (Str.startswith("0")) - return 8; - - return 10; -} - - -/// GetAsUnsignedInteger - Workhorse method that converts a integer character -/// sequence of radix up to 36 to an unsigned long long value. -bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix, - unsigned long long &Result) { - // Autosense radix if not specified. - if (Radix == 0) - Radix = GetAutoSenseRadix(Str); - - // Empty strings (after the radix autosense) are invalid. - if (Str.empty()) return true; - - // Parse all the bytes of the string given this radix. Watch for overflow. - Result = 0; - while (!Str.empty()) { - unsigned CharVal; - if (Str[0] >= '0' && Str[0] <= '9') - CharVal = Str[0]-'0'; - else if (Str[0] >= 'a' && Str[0] <= 'z') - CharVal = Str[0]-'a'+10; - else if (Str[0] >= 'A' && Str[0] <= 'Z') - CharVal = Str[0]-'A'+10; - else - return true; - - // If the parsed value is larger than the integer radix, the string is - // invalid. - if (CharVal >= Radix) - return true; - - // Add in this character. - unsigned long long PrevResult = Result; - Result = Result*Radix+CharVal; - - // Check for overflow by shifting back and seeing if bits were lost. - if (Result/Radix < PrevResult) - return true; - - Str = Str.substr(1); - } - - return false; -} - -bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix, - long long &Result) { - unsigned long long ULLVal; - - // Handle positive strings first. - if (Str.empty() || Str.front() != '-') { - if (getAsUnsignedInteger(Str, Radix, ULLVal) || - // Check for value so large it overflows a signed value. - (long long)ULLVal < 0) - return true; - Result = ULLVal; - return false; - } - - // Get the positive part of the value. - if (getAsUnsignedInteger(Str.substr(1), Radix, ULLVal) || - // Reject values so large they'd overflow as negative signed, but allow - // "-0". This negates the unsigned so that the negative isn't undefined - // on signed overflow. - (long long)-ULLVal > 0) - return true; - - Result = -ULLVal; - return false; -} - -// Implementation of StringRef hashing. -hash_code llvm::hash_value(StringRef S) { - return hash_combine_range(S.begin(), S.end()); -} diff --git a/wpiutil/src/llvm/raw_os_ostream.cpp b/wpiutil/src/llvm/raw_os_ostream.cpp deleted file mode 100644 index 402004e..0000000 --- a/wpiutil/src/llvm/raw_os_ostream.cpp +++ /dev/null @@ -1,30 +0,0 @@ -//===--- raw_os_ostream.cpp - Implement the raw_os_ostream class ----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This implements support adapting raw_ostream to std::ostream. -// -//===----------------------------------------------------------------------===// - -#include "llvm/raw_os_ostream.h" -#include -using namespace llvm; - -//===----------------------------------------------------------------------===// -// raw_os_ostream -//===----------------------------------------------------------------------===// - -raw_os_ostream::~raw_os_ostream() { - flush(); -} - -void raw_os_ostream::write_impl(const char *Ptr, size_t Size) { - OS.write(Ptr, Size); -} - -uint64_t raw_os_ostream::current_pos() const { return OS.tellp(); } diff --git a/wpiutil/src/llvm/raw_ostream.cpp b/wpiutil/src/llvm/raw_ostream.cpp deleted file mode 100644 index 8ddbcc6..0000000 --- a/wpiutil/src/llvm/raw_ostream.cpp +++ /dev/null @@ -1,855 +0,0 @@ -//===--- raw_ostream.cpp - Implement the raw_ostream classes --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This implements support for bulk buffered stream output. -// -//===----------------------------------------------------------------------===// - -#include "llvm/raw_ostream.h" -#include "llvm/SmallString.h" -#include "llvm/SmallVector.h" -#include "llvm/StringExtras.h" -#include "llvm/Compiler.h" -#include "llvm/Format.h" -#include "llvm/MathExtras.h" -#include "llvm/WindowsError.h" -#include -#include -#include -#include - -// may provide O_BINARY. -#include - -#ifndef _WIN32 -#include -#include -#endif - -#if defined(__CYGWIN__) -#include -#endif - -#if defined(_MSC_VER) -#include -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -# define STDOUT_FILENO 1 -#endif -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif -#endif - -#if defined(_WIN32) -#include - -/// Determines if the program is running on Windows 8 or newer. This -/// reimplements one of the helpers in the Windows 8.1 SDK, which are intended -/// to supercede raw calls to GetVersionEx. Old SDKs, Cygwin, and MinGW don't -/// yet have VersionHelpers.h, so we have our own helper. -static inline bool RunningWindows8OrGreater() { - // Windows 8 is version 6.2, service pack 0. - OSVERSIONINFOEXW osvi = {}; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - osvi.dwMajorVersion = 6; - osvi.dwMinorVersion = 2; - osvi.wServicePackMajor = 0; - - DWORDLONG Mask = 0; - Mask = VerSetConditionMask(Mask, VER_MAJORVERSION, VER_GREATER_EQUAL); - Mask = VerSetConditionMask(Mask, VER_MINORVERSION, VER_GREATER_EQUAL); - Mask = VerSetConditionMask(Mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - - return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | - VER_SERVICEPACKMAJOR, - Mask) != FALSE; -} - -static std::error_code UTF8ToUTF16(llvm::StringRef utf8, - llvm::SmallVectorImpl &utf16) { - if (!utf8.empty()) { - int len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8.begin(), - utf8.size(), utf16.begin(), 0); - - if (len == 0) - return llvm::mapWindowsError(::GetLastError()); - - utf16.reserve(len + 1); - utf16.set_size(len); - - len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8.begin(), - utf8.size(), utf16.begin(), utf16.size()); - - if (len == 0) - return llvm::mapWindowsError(::GetLastError()); - } - - // Make utf16 null terminated. - utf16.push_back(0); - utf16.pop_back(); - - return std::error_code(); -} - -#endif - -using namespace llvm; - -raw_ostream::~raw_ostream() { - // raw_ostream's subclasses should take care to flush the buffer - // in their destructors. - assert(OutBufCur == OutBufStart && - "raw_ostream destructor called with non-empty buffer!"); - - if (BufferMode == InternalBuffer) - delete [] OutBufStart; -} - -// An out of line virtual method to provide a home for the class vtable. -void raw_ostream::handle() {} - -size_t raw_ostream::preferred_buffer_size() const { - // BUFSIZ is intended to be a reasonable default. - return BUFSIZ; -} - -void raw_ostream::SetBuffered() { - // Ask the subclass to determine an appropriate buffer size. - if (size_t Size = preferred_buffer_size()) - SetBufferSize(Size); - else - // It may return 0, meaning this stream should be unbuffered. - SetUnbuffered(); -} - -void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, - BufferKind Mode) { - assert(((Mode == Unbuffered && !BufferStart && Size == 0) || - (Mode != Unbuffered && BufferStart && Size != 0)) && - "stream must be unbuffered or have at least one byte"); - // Make sure the current buffer is free of content (we can't flush here; the - // child buffer management logic will be in write_impl). - assert(GetNumBytesInBuffer() == 0 && "Current buffer is non-empty!"); - - if (BufferMode == InternalBuffer) - delete [] OutBufStart; - OutBufStart = BufferStart; - OutBufEnd = OutBufStart+Size; - OutBufCur = OutBufStart; - BufferMode = Mode; - - assert(OutBufStart <= OutBufEnd && "Invalid size!"); -} - -raw_ostream &raw_ostream::operator<<(unsigned long N) { - // Zero is a special case. - if (N == 0) - return *this << '0'; - - char NumberBuffer[20]; - char *EndPtr = NumberBuffer+sizeof(NumberBuffer); - char *CurPtr = EndPtr; - - while (N) { - *--CurPtr = '0' + char(N % 10); - N /= 10; - } - return write(CurPtr, EndPtr-CurPtr); -} - -raw_ostream &raw_ostream::operator<<(long N) { - if (N < 0) { - *this << '-'; - // Avoid undefined behavior on LONG_MIN with a cast. - N = -(unsigned long)N; - } - - return this->operator<<(static_cast(N)); -} - -raw_ostream &raw_ostream::operator<<(unsigned long long N) { - // Output using 32-bit div/mod when possible. - if (N == static_cast(N)) - return this->operator<<(static_cast(N)); - - char NumberBuffer[20]; - char *EndPtr = std::end(NumberBuffer); - char *CurPtr = EndPtr; - - while (N) { - *--CurPtr = '0' + char(N % 10); - N /= 10; - } - return write(CurPtr, EndPtr-CurPtr); -} - -raw_ostream &raw_ostream::operator<<(long long N) { - if (N < 0) { - *this << '-'; - // Avoid undefined behavior on INT64_MIN with a cast. - N = -(unsigned long long)N; - } - - return this->operator<<(static_cast(N)); -} - -raw_ostream &raw_ostream::write_hex(unsigned long long N) { - // Zero is a special case. - if (N == 0) - return *this << '0'; - - char NumberBuffer[16]; - char *EndPtr = std::end(NumberBuffer); - char *CurPtr = EndPtr; - - while (N) { - unsigned char x = static_cast(N) % 16; - *--CurPtr = hexdigit(x, /*LowerCase*/true); - N /= 16; - } - - return write(CurPtr, EndPtr-CurPtr); -} - -raw_ostream &raw_ostream::write_escaped(StringRef Str, - bool UseHexEscapes) { - for (unsigned char c : Str) { - switch (c) { - case '\\': - *this << '\\' << '\\'; - break; - case '\t': - *this << '\\' << 't'; - break; - case '\n': - *this << '\\' << 'n'; - break; - case '"': - *this << '\\' << '"'; - break; - default: - if (std::isprint(c)) { - *this << c; - break; - } - - // Write out the escaped representation. - if (UseHexEscapes) { - *this << '\\' << 'x'; - *this << hexdigit((c >> 4 & 0xF)); - *this << hexdigit((c >> 0) & 0xF); - } else { - // Always use a full 3-character octal escape. - *this << '\\'; - *this << char('0' + ((c >> 6) & 7)); - *this << char('0' + ((c >> 3) & 7)); - *this << char('0' + ((c >> 0) & 7)); - } - } - } - - return *this; -} - -raw_ostream &raw_ostream::operator<<(const void *P) { - *this << '0' << 'x'; - - return write_hex((uintptr_t) P); -} - -raw_ostream &raw_ostream::operator<<(double N) { -#ifdef _WIN32 - // On MSVCRT and compatible, output of %e is incompatible to Posix - // by default. Number of exponent digits should be at least 2. "%+03d" - // FIXME: Implement our formatter to here or Support/Format.h! -#if defined(__MINGW32__) - // FIXME: It should be generic to C++11. - if (N == 0.0 && std::signbit(N)) - return *this << "-0.000000e+00"; -#else - int fpcl = _fpclass(N); - - // negative zero - if (fpcl == _FPCLASS_NZ) - return *this << "-0.000000e+00"; -#endif - - char buf[16]; - unsigned len; - len = format("%e", N).snprint(buf, sizeof(buf)); - if (len <= sizeof(buf) - 2) { - if (len >= 5 && buf[len - 5] == 'e' && buf[len - 3] == '0') { - int cs = buf[len - 4]; - if (cs == '+' || cs == '-') { - int c1 = buf[len - 2]; - int c0 = buf[len - 1]; - if (isdigit(static_cast(c1)) && - isdigit(static_cast(c0))) { - // Trim leading '0': "...e+012" -> "...e+12\0" - buf[len - 3] = c1; - buf[len - 2] = c0; - buf[--len] = 0; - } - } - } - return this->operator<<(buf); - } -#endif - return this->operator<<(format("%e", N)); -} - - - -void raw_ostream::flush_nonempty() { - assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty."); - size_t Length = OutBufCur - OutBufStart; - OutBufCur = OutBufStart; - write_impl(OutBufStart, Length); -} - -raw_ostream &raw_ostream::write(unsigned char C) { - // Group exceptional cases into a single branch. - if (LLVM_UNLIKELY(OutBufCur >= OutBufEnd)) { - if (LLVM_UNLIKELY(!OutBufStart)) { - if (BufferMode == Unbuffered) { - write_impl(reinterpret_cast(&C), 1); - return *this; - } - // Set up a buffer and start over. - SetBuffered(); - return write(C); - } - - flush_nonempty(); - } - - *OutBufCur++ = C; - return *this; -} - -raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) { - // Group exceptional cases into a single branch. - if (LLVM_UNLIKELY(size_t(OutBufEnd - OutBufCur) < Size)) { - if (LLVM_UNLIKELY(!OutBufStart)) { - if (BufferMode == Unbuffered) { - write_impl(Ptr, Size); - return *this; - } - // Set up a buffer and start over. - SetBuffered(); - return write(Ptr, Size); - } - - size_t NumBytes = OutBufEnd - OutBufCur; - - // If the buffer is empty at this point we have a string that is larger - // than the buffer. Directly write the chunk that is a multiple of the - // preferred buffer size and put the remainder in the buffer. - if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) { - assert(NumBytes != 0 && "undefined behavior"); - size_t BytesToWrite = Size - (Size % NumBytes); - write_impl(Ptr, BytesToWrite); - size_t BytesRemaining = Size - BytesToWrite; - if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) { - // Too much left over to copy into our buffer. - return write(Ptr + BytesToWrite, BytesRemaining); - } - copy_to_buffer(Ptr + BytesToWrite, BytesRemaining); - return *this; - } - - // We don't have enough space in the buffer to fit the string in. Insert as - // much as possible, flush and start over with the remainder. - copy_to_buffer(Ptr, NumBytes); - flush_nonempty(); - return write(Ptr + NumBytes, Size - NumBytes); - } - - copy_to_buffer(Ptr, Size); - - return *this; -} - -void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) { - assert(Size <= size_t(OutBufEnd - OutBufCur) && "Buffer overrun!"); - - // Handle short strings specially, memcpy isn't very good at very short - // strings. - switch (Size) { - case 4: OutBufCur[3] = Ptr[3]; // FALL THROUGH - case 3: OutBufCur[2] = Ptr[2]; // FALL THROUGH - case 2: OutBufCur[1] = Ptr[1]; // FALL THROUGH - case 1: OutBufCur[0] = Ptr[0]; // FALL THROUGH - case 0: break; - default: - memcpy(OutBufCur, Ptr, Size); - break; - } - - OutBufCur += Size; -} - -// Formatted output. -raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) { - // If we have more than a few bytes left in our output buffer, try - // formatting directly onto its end. - size_t NextBufferSize = 127; - size_t BufferBytesLeft = OutBufEnd - OutBufCur; - if (BufferBytesLeft > 3) { - size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft); - - // Common case is that we have plenty of space. - if (BytesUsed <= BufferBytesLeft) { - OutBufCur += BytesUsed; - return *this; - } - - // Otherwise, we overflowed and the return value tells us the size to try - // again with. - NextBufferSize = BytesUsed; - } - - // If we got here, we didn't have enough space in the output buffer for the - // string. Try printing into a SmallVector that is resized to have enough - // space. Iterate until we win. - SmallVector V; - - while (1) { - V.resize(NextBufferSize); - - // Try formatting into the SmallVector. - size_t BytesUsed = Fmt.print(V.data(), NextBufferSize); - - // If BytesUsed fit into the vector, we win. - if (BytesUsed <= NextBufferSize) - return write(V.data(), BytesUsed); - - // Otherwise, try again with a new size. - assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?"); - NextBufferSize = BytesUsed; - } -} - -raw_ostream &raw_ostream::operator<<(const FormattedString &FS) { - unsigned Len = FS.Str.size(); - int PadAmount = FS.Width - Len; - if (FS.RightJustify && (PadAmount > 0)) - this->indent(PadAmount); - this->operator<<(FS.Str); - if (!FS.RightJustify && (PadAmount > 0)) - this->indent(PadAmount); - return *this; -} - -raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) { - if (FN.Hex) { - unsigned Nibbles = (64 - countLeadingZeros(FN.HexValue)+3)/4; - unsigned PrefixChars = FN.HexPrefix ? 2 : 0; - unsigned Width = std::max(FN.Width, Nibbles + PrefixChars); - - char NumberBuffer[20] = "0x0000000000000000"; - if (!FN.HexPrefix) - NumberBuffer[1] = '0'; - char *EndPtr = NumberBuffer+Width; - char *CurPtr = EndPtr; - unsigned long long N = FN.HexValue; - while (N) { - unsigned char x = static_cast(N) % 16; - *--CurPtr = hexdigit(x, !FN.Upper); - N /= 16; - } - - return write(NumberBuffer, Width); - } else { - // Zero is a special case. - if (FN.DecValue == 0) { - this->indent(FN.Width-1); - return *this << '0'; - } - char NumberBuffer[32]; - char *EndPtr = NumberBuffer+sizeof(NumberBuffer); - char *CurPtr = EndPtr; - bool Neg = (FN.DecValue < 0); - uint64_t N = Neg ? -static_cast(FN.DecValue) : FN.DecValue; - while (N) { - *--CurPtr = '0' + char(N % 10); - N /= 10; - } - int Len = EndPtr - CurPtr; - int Pad = FN.Width - Len; - if (Neg) - --Pad; - if (Pad > 0) - this->indent(Pad); - if (Neg) - *this << '-'; - return write(CurPtr, Len); - } -} - - -/// indent - Insert 'NumSpaces' spaces. -raw_ostream &raw_ostream::indent(unsigned NumSpaces) { - static const char Spaces[] = " " - " " - " "; - - // Usually the indentation is small, handle it with a fastpath. - if (NumSpaces < array_lengthof(Spaces)) - return write(Spaces, NumSpaces); - - while (NumSpaces) { - unsigned NumToWrite = std::min(NumSpaces, - (unsigned)array_lengthof(Spaces)-1); - write(Spaces, NumToWrite); - NumSpaces -= NumToWrite; - } - return *this; -} - - -//===----------------------------------------------------------------------===// -// Formatted Output -//===----------------------------------------------------------------------===// - -// Out of line virtual method. -void format_object_base::home() { -} - -//===----------------------------------------------------------------------===// -// raw_fd_ostream -//===----------------------------------------------------------------------===// - -static int getFD(StringRef Filename, std::error_code &EC, - sys::fs::OpenFlags Flags) { - // Handle "-" as stdout. Note that when we do this, we consider ourself - // the owner of stdout. This means that we can do things like close the - // file descriptor when we're done and set the "binary" flag globally. - if (Filename == "-") { - EC = std::error_code(); - // If user requested binary then put stdout into binary mode if - // possible. - if (!(Flags & sys::fs::F_Text)) { -#if defined(_WIN32) - _setmode(_fileno(stdout), _O_BINARY); -#endif - } - return STDOUT_FILENO; - } - - int FD; - - //EC = sys::fs::openFileForWrite(Filename, FD, Flags); - //if (EC) - // return -1; -#if defined(_WIN32) - // Verify that we don't have both "append" and "excl". - assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) && - "Cannot specify both 'excl' and 'append' file creation flags!"); - - SmallVector PathUTF16; - - EC = UTF8ToUTF16(Filename, PathUTF16); - if (EC) return -1; - - DWORD CreationDisposition; - if (Flags & sys::fs::F_Excl) - CreationDisposition = CREATE_NEW; - else if (Flags & sys::fs::F_Append) - CreationDisposition = OPEN_ALWAYS; - else - CreationDisposition = CREATE_ALWAYS; - - DWORD Access = GENERIC_WRITE; - if (Flags & sys::fs::F_RW) - Access |= GENERIC_READ; - - HANDLE H = ::CreateFileW(PathUTF16.begin(), Access, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - CreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL); - - if (H == INVALID_HANDLE_VALUE) { - DWORD LastError = ::GetLastError(); - EC = mapWindowsError(LastError); - return -1; - } - - int OpenFlags = 0; - if (Flags & sys::fs::F_Append) - OpenFlags |= _O_APPEND; - - if (Flags & sys::fs::F_Text) - OpenFlags |= _O_TEXT; - - FD = ::_open_osfhandle(intptr_t(H), OpenFlags); - if (FD == -1) { - ::CloseHandle(H); - EC = mapWindowsError(ERROR_INVALID_HANDLE); - return -1; - } -#else - // Verify that we don't have both "append" and "excl". - assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) && - "Cannot specify both 'excl' and 'append' file creation flags!"); - - int OpenFlags = O_CREAT; - - if (Flags & sys::fs::F_RW) - OpenFlags |= O_RDWR; - else - OpenFlags |= O_WRONLY; - - if (Flags & sys::fs::F_Append) - OpenFlags |= O_APPEND; - else - OpenFlags |= O_TRUNC; - - if (Flags & sys::fs::F_Excl) - OpenFlags |= O_EXCL; - - SmallString<128> Storage{Filename}; - while ((FD = open(Storage.c_str(), OpenFlags, 0666)) < 0) { - if (errno != EINTR) { - EC = std::error_code(errno, std::generic_category()); - return -1; - } - } -#endif - - EC = std::error_code(); - return FD; -} - -raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC, - sys::fs::OpenFlags Flags) - : raw_fd_ostream(getFD(Filename, EC, Flags), true) {} - -/// FD is the file descriptor that this writes to. If ShouldClose is true, this -/// closes the file when the stream is destroyed. -raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered) - : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose), - Error(false) { - if (FD < 0 ) { - ShouldClose = false; - return; - } - - // Get the starting position. - off_t loc = ::lseek(FD, 0, SEEK_CUR); -#ifdef _WIN32 - // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes. - SupportsSeeking = loc != (off_t)-1 && ::GetFileType(reinterpret_cast(::_get_osfhandle(FD))) != FILE_TYPE_PIPE; -#else - SupportsSeeking = loc != (off_t)-1; -#endif - if (!SupportsSeeking) - pos = 0; - else - pos = static_cast(loc); -} - -raw_fd_ostream::~raw_fd_ostream() { - if (FD >= 0) { - flush(); - if (ShouldClose && ::close(FD) < 0) - error_detected(); - } - -#ifdef __MINGW32__ - // On mingw, global dtors should not call exit(). - // report_fatal_error() invokes exit(). We know report_fatal_error() - // might not write messages to stderr when any errors were detected - // on FD == 2. - if (FD == 2) return; -#endif -} - - -void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { - assert(FD >= 0 && "File already closed."); - pos += Size; - -#ifndef _WIN32 - bool ShouldWriteInChunks = false; -#else - // Writing a large size of output to Windows console returns ENOMEM. It seems - // that, prior to Windows 8, WriteFile() is redirecting to WriteConsole(), and - // the latter has a size limit (66000 bytes or less, depending on heap usage). - bool ShouldWriteInChunks = !!::_isatty(FD) && !RunningWindows8OrGreater(); -#endif - - do { - size_t ChunkSize = Size; - if (ChunkSize > 32767 && ShouldWriteInChunks) - ChunkSize = 32767; - -#ifdef _WIN32 - int ret = ::_write(FD, Ptr, ChunkSize); -#else - ssize_t ret = ::write(FD, Ptr, ChunkSize); -#endif - - if (ret < 0) { - // If it's a recoverable error, swallow it and retry the write. - // - // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since - // raw_ostream isn't designed to do non-blocking I/O. However, some - // programs, such as old versions of bjam, have mistakenly used - // O_NONBLOCK. For compatibility, emulate blocking semantics by - // spinning until the write succeeds. If you don't want spinning, - // don't use O_NONBLOCK file descriptors with raw_ostream. - if (errno == EINTR || errno == EAGAIN -#ifdef EWOULDBLOCK - || errno == EWOULDBLOCK -#endif - ) - continue; - - // Otherwise it's a non-recoverable error. Note it and quit. - error_detected(); - break; - } - - // The write may have written some or all of the data. Update the - // size and buffer pointer to reflect the remainder that needs - // to be written. If there are no bytes left, we're done. - Ptr += ret; - Size -= ret; - } while (Size > 0); -} - -void raw_fd_ostream::close() { - assert(ShouldClose); - ShouldClose = false; - flush(); - if (::close(FD) < 0) - error_detected(); - FD = -1; -} - -uint64_t raw_fd_ostream::seek(uint64_t off) { - assert(SupportsSeeking && "Stream does not support seeking!"); - flush(); - pos = ::lseek(FD, off, SEEK_SET); - if (pos == (uint64_t)-1) - error_detected(); - return pos; -} - -void raw_fd_ostream::pwrite_impl(const char *Ptr, size_t Size, - uint64_t Offset) { - uint64_t Pos = tell(); - seek(Offset); - write(Ptr, Size); - seek(Pos); -} - -size_t raw_fd_ostream::preferred_buffer_size() const { -#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__minix) - // Windows and Minix have no st_blksize. - assert(FD >= 0 && "File not yet open!"); - struct stat statbuf; - if (fstat(FD, &statbuf) != 0) - return 0; - - // If this is a terminal, don't use buffering. Line buffering - // would be a more traditional thing to do, but it's not worth - // the complexity. - if (S_ISCHR(statbuf.st_mode) && isatty(FD)) - return 0; - // Return the preferred block size. - return statbuf.st_blksize; -#else - return raw_ostream::preferred_buffer_size(); -#endif -} - -//===----------------------------------------------------------------------===// -// outs(), errs(), nulls() -//===----------------------------------------------------------------------===// - -/// outs() - This returns a reference to a raw_ostream for standard output. -/// Use it like: outs() << "foo" << "bar"; -raw_ostream &llvm::outs() { - // Set buffer settings to model stdout behavior. Delete the file descriptor - // when the program exits, forcing error detection. This means that if you - // ever call outs(), you can't open another raw_fd_ostream on stdout, as we'll - // close stdout twice and print an error the second time. - std::error_code EC; - static raw_fd_ostream S("-", EC, sys::fs::F_None); - assert(!EC); - return S; -} - -/// errs() - This returns a reference to a raw_ostream for standard error. -/// Use it like: errs() << "foo" << "bar"; -raw_ostream &llvm::errs() { - // Set standard error to be unbuffered by default. - static raw_fd_ostream S(STDERR_FILENO, false, true); - return S; -} - -/// nulls() - This returns a reference to a raw_ostream which discards output. -raw_ostream &llvm::nulls() { - static raw_null_ostream S; - return S; -} - - -//===----------------------------------------------------------------------===// -// raw_string_ostream -//===----------------------------------------------------------------------===// - -raw_string_ostream::~raw_string_ostream() { - flush(); -} - -void raw_string_ostream::write_impl(const char *Ptr, size_t Size) { - OS.append(Ptr, Size); -} - -//===----------------------------------------------------------------------===// -// raw_svector_ostream -//===----------------------------------------------------------------------===// - -uint64_t raw_svector_ostream::current_pos() const { return OS.size(); } - -void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { - OS.append(Ptr, Ptr + Size); -} - -void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size, - uint64_t Offset) { - memcpy(OS.data() + Offset, Ptr, Size); -} - -//===----------------------------------------------------------------------===// -// raw_null_ostream -//===----------------------------------------------------------------------===// - -raw_null_ostream::~raw_null_ostream() { -#ifndef NDEBUG - // ~raw_ostream asserts that the buffer is empty. This isn't necessary - // with raw_null_ostream, but it's better to have raw_null_ostream follow - // the rules than to change the rules just for raw_null_ostream. - flush(); -#endif -} - -void raw_null_ostream::write_impl(const char * /*Ptr*/, size_t /*Size*/) {} - -uint64_t raw_null_ostream::current_pos() const { - return 0; -} - -void raw_null_ostream::pwrite_impl(const char * /*Ptr*/, size_t /*Size*/, - uint64_t /*Offset*/) {} diff --git a/wpiutil/src/support/Base64.cpp b/wpiutil/src/support/Base64.cpp deleted file mode 100644 index 88fe28a..0000000 --- a/wpiutil/src/support/Base64.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -/* ==================================================================== - * Copyright (c) 1995-1999 The Apache Group. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see . - * - */ - -#include "support/Base64.h" - -namespace wpi { - -// aaaack but it's fast and const should make it shared text page. -static const unsigned char pr2six[256] = -{ - // ASCII table - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, - 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, - 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 -}; - -std::size_t Base64Decode(llvm::StringRef encoded, std::string* plain) { - const unsigned char *end = encoded.bytes_begin(); - while (pr2six[*end] <= 63 && end != encoded.bytes_end()) ++end; - std::size_t nprbytes = end - encoded.bytes_begin(); - - plain->clear(); - if (nprbytes == 0) - return 0; - plain->reserve(((nprbytes + 3) / 4) * 3); - - const unsigned char *cur = encoded.bytes_begin(); - - while (nprbytes > 4) { - (*plain) += (pr2six[cur[0]] << 2 | pr2six[cur[1]] >> 4); - (*plain) += (pr2six[cur[1]] << 4 | pr2six[cur[2]] >> 2); - (*plain) += (pr2six[cur[2]] << 6 | pr2six[cur[3]]); - cur += 4; - nprbytes -= 4; - } - - // Note: (nprbytes == 1) would be an error, so just ignore that case - if (nprbytes > 1) (*plain) += (pr2six[cur[0]] << 2 | pr2six[cur[1]] >> 4); - if (nprbytes > 2) (*plain) += (pr2six[cur[1]] << 4 | pr2six[cur[2]] >> 2); - if (nprbytes > 3) (*plain) += (pr2six[cur[2]] << 6 | pr2six[cur[3]]); - - return (end - encoded.bytes_begin()) + ((4 - nprbytes) & 3); -} - -static const char basis_64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -void Base64Encode(llvm::StringRef plain, std::string* encoded) { - encoded->clear(); - if (plain.empty()) - return; - std::size_t len = plain.size(); - encoded->reserve(((len + 2) / 3 * 4) + 1); - - std::size_t i; - for (i = 0; (i + 2) < len; i += 3) { - (*encoded) += basis_64[(plain[i] >> 2) & 0x3F]; - (*encoded) += - basis_64[((plain[i] & 0x3) << 4) | ((int)(plain[i + 1] & 0xF0) >> 4)]; - (*encoded) += basis_64[((plain[i + 1] & 0xF) << 2) | - ((int)(plain[i + 2] & 0xC0) >> 6)]; - (*encoded) += basis_64[plain[i + 2] & 0x3F]; - } - if (i < len) { - (*encoded) += basis_64[(plain[i] >> 2) & 0x3F]; - if (i == (len - 1)) { - (*encoded) += basis_64[((plain[i] & 0x3) << 4)]; - (*encoded) += '='; - } else { - (*encoded) += - basis_64[((plain[i] & 0x3) << 4) | ((int)(plain[i + 1] & 0xF0) >> 4)]; - (*encoded) += basis_64[((plain[i + 1] & 0xF) << 2)]; - } - (*encoded) += '='; - } -} - -} // namespace wpi diff --git a/wpiutil/src/support/leb128.cpp b/wpiutil/src/support/leb128.cpp deleted file mode 100644 index 11605bc..0000000 --- a/wpiutil/src/support/leb128.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#include "support/leb128.h" - -#include "support/raw_istream.h" - -namespace wpi { - -/** - * Get size of unsigned LEB128 data - * @val: value - * - * Determine the number of bytes required to encode an unsigned LEB128 datum. - * The algorithm is taken from Appendix C of the DWARF 3 spec. For information - * on the encodings refer to section "7.6 - Variable Length Data". Return - * the number of bytes required. - */ -std::size_t SizeUleb128(unsigned long val) { - std::size_t count = 0; - do { - val >>= 7; - ++count; - } while (val != 0); - return count; -} - -/** - * Write unsigned LEB128 data - * @addr: the address where the ULEB128 data is to be stored - * @val: value to be stored - * - * Encode an unsigned LEB128 encoded datum. The algorithm is taken - * from Appendix C of the DWARF 3 spec. For information on the - * encodings refer to section "7.6 - Variable Length Data". Return - * the number of bytes written. - */ -std::size_t WriteUleb128(llvm::SmallVectorImpl& dest, unsigned long val) { - std::size_t count = 0; - - do { - unsigned char byte = val & 0x7f; - val >>= 7; - - if (val != 0) - byte |= 0x80; // mark this byte to show that more bytes will follow - - dest.push_back(byte); - count++; - } while (val != 0); - - return count; -} - -/** - * Read unsigned LEB128 data - * @addr: the address where the ULEB128 data is stored - * @ret: address to store the result - * - * Decode an unsigned LEB128 encoded datum. The algorithm is taken - * from Appendix C of the DWARF 3 spec. For information on the - * encodings refer to section "7.6 - Variable Length Data". Return - * the number of bytes read. - */ -std::size_t ReadUleb128(const char* addr, unsigned long* ret) { - unsigned long result = 0; - int shift = 0; - std::size_t count = 0; - - while (1) { - unsigned char byte = *reinterpret_cast(addr); - addr++; - count++; - - result |= (byte & 0x7f) << shift; - shift += 7; - - if (!(byte & 0x80)) break; - } - - *ret = result; - - return count; -} - -/** - * Read unsigned LEB128 data from a stream - * @is: the input stream where the ULEB128 data is to be read from - * @ret: address to store the result - * - * Decode an unsigned LEB128 encoded datum. The algorithm is taken - * from Appendix C of the DWARF 3 spec. For information on the - * encodings refer to section "7.6 - Variable Length Data". Return - * false on stream error, true on success. - */ -bool ReadUleb128(raw_istream& is, unsigned long* ret) { - unsigned long result = 0; - int shift = 0; - - while (1) { - unsigned char byte; - is.read((char*)&byte, 1); - if (is.has_error()) return false; - - result |= (byte & 0x7f) << shift; - shift += 7; - - if (!(byte & 0x80)) break; - } - - *ret = result; - - return true; -} - -} // namespace wpi diff --git a/wpiutil/src/support/raw_istream.cpp b/wpiutil/src/support/raw_istream.cpp deleted file mode 100644 index 2863a61..0000000 --- a/wpiutil/src/support/raw_istream.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#include "support/raw_istream.h" - -#include -#include - -#ifdef _WIN32 -#include -#else -#include -#endif - -using namespace wpi; - -void raw_mem_istream::close() {} - -std::size_t raw_mem_istream::in_avail() const { return m_left; } - -void raw_mem_istream::read_impl(void* data, std::size_t len) { - if (len > m_left) { - error_detected(); - return; - } - std::memcpy(data, m_cur, len); - m_cur += len; - m_left -= len; -} - -raw_fd_istream::raw_fd_istream(int fd, bool shouldClose, std::size_t bufSize) - : m_bufSize(bufSize), m_fd(fd), m_shouldClose(shouldClose) { - m_cur = m_end = m_buf = static_cast(std::malloc(bufSize)); -} - -raw_fd_istream::~raw_fd_istream() { - if (m_shouldClose) close(); - std::free(m_buf); -} - -void raw_fd_istream::close() { - if (m_fd >= 0) { - ::close(m_fd); - m_fd = -1; - } -} - -std::size_t raw_fd_istream::in_avail() const { return m_end - m_cur; } - -void raw_fd_istream::read_impl(void* data, std::size_t len) { - std::size_t left = m_end - m_cur; - if (left < len) { - // not enough data - if (m_cur == m_end) { -#ifdef _WIN32 - int count = ::_read(m_fd, m_buf, m_bufSize); -#else - ssize_t count = ::read(m_fd, m_buf, m_bufSize); -#endif - if (count < 0) { - error_detected(); - return; - } - m_cur = m_buf; - m_end = m_buf + count; - return read_impl(data, len); - } - - std::memcpy(data, m_cur, left); - return read_impl(static_cast(data) + left, len - left); - } - - std::memcpy(data, m_cur, len); - m_cur += len; -} diff --git a/wpiutil/src/support/raw_socket_istream.cpp b/wpiutil/src/support/raw_socket_istream.cpp deleted file mode 100644 index 4f27dfb..0000000 --- a/wpiutil/src/support/raw_socket_istream.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#include "support/raw_socket_istream.h" -#include "tcpsockets/NetworkStream.h" - -using namespace wpi; - -void raw_socket_istream::read_impl(void* data, std::size_t len) { - char* cdata = static_cast(data); - std::size_t pos = 0; - - while (pos < len) { - NetworkStream::Error err; - std::size_t count = - m_stream.receive(&cdata[pos], len - pos, &err, m_timeout); - if (count == 0) { - error_detected(); - return; - } - pos += count; - } -} - -void raw_socket_istream::close() { m_stream.close(); } - -std::size_t raw_socket_istream::in_avail() const { return 0; } diff --git a/wpiutil/src/support/raw_socket_ostream.cpp b/wpiutil/src/support/raw_socket_ostream.cpp deleted file mode 100644 index 67bcd8c..0000000 --- a/wpiutil/src/support/raw_socket_ostream.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#include "support/raw_socket_ostream.h" -#include "tcpsockets/NetworkStream.h" - -using namespace wpi; - -raw_socket_ostream::~raw_socket_ostream() { - flush(); - if (m_shouldClose) close(); -} - -void raw_socket_ostream::write_impl(const char* data, std::size_t len) { - std::size_t pos = 0; - - while (pos < len) { - NetworkStream::Error err; - std::size_t count = - m_stream.send(&data[pos], len - pos, &err); - if (count == 0) { - error_detected(); - return; - } - pos += count; - } -} - -uint64_t raw_socket_ostream::current_pos() const { return 0; } - -void raw_socket_ostream::close() { - if (!m_shouldClose) return; - flush(); - m_stream.close(); -} diff --git a/wpiutil/src/support/timestamp.cpp b/wpiutil/src/support/timestamp.cpp deleted file mode 100644 index 9b21e5e..0000000 --- a/wpiutil/src/support/timestamp.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ -#include "support/timestamp.h" - -#ifdef _WIN32 -#include -#include -#include -#else -#include -#endif - -// offset in microseconds -static unsigned long long zerotime() { -#ifdef _WIN32 - FILETIME ft; - unsigned long long tmpres = 0; - // 100-nanosecond intervals since January 1, 1601 (UTC) - // which means 0.1 us - GetSystemTimeAsFileTime(&ft); - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - // January 1st, 1970 - January 1st, 1601 UTC ~ 369 years - // or 116444736000000000 us - static const unsigned long long deltaepoch = 116444736000000000ull; - tmpres -= deltaepoch; - return tmpres; -#else - // 100-ns intervals - using namespace std::chrono; - return duration_cast( - high_resolution_clock::now().time_since_epoch()).count() / 100u; -#endif -} - -static unsigned long long timestamp() { -#ifdef _WIN32 - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - // there is an imprecision with the initial value, - // but what matters is that timestamps are monotonic and consistent - return static_cast(li.QuadPart); -#else - // 100-ns intervals - using namespace std::chrono; - return duration_cast( - steady_clock::now().time_since_epoch()).count() / 100u; -#endif -} - -#ifdef _WIN32 -static unsigned long long update_frequency() { - LARGE_INTEGER li; - if (!QueryPerformanceFrequency(&li) || !li.QuadPart) { - // log something - std::terminate(); - } - return static_cast(li.QuadPart); -} -#endif - -static const unsigned long long zerotime_val = zerotime(); -static const unsigned long long offset_val = timestamp(); -#ifdef _WIN32 -static const unsigned long long frequency_val = update_frequency(); -#endif - -unsigned long long wpi::Now() { -#ifdef _WIN32 - assert(offset_val > 0u); - assert(frequency_val > 0u); - unsigned long long delta = timestamp() - offset_val; - // because the frequency is in update per seconds, we have to multiply the - // delta by 10,000,000 - unsigned long long delta_in_us = delta * 10000000ull / frequency_val; - return delta_in_us + zerotime_val; -#else - return zerotime_val + timestamp() - offset_val; -#endif -} - -unsigned long long WPI_Now() { - return wpi::Now(); -} diff --git a/wpiutil/src/tcpsockets/SocketError.cpp b/wpiutil/src/tcpsockets/SocketError.cpp deleted file mode 100644 index a2628fd..0000000 --- a/wpiutil/src/tcpsockets/SocketError.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#include "tcpsockets/SocketError.h" - -#ifdef _WIN32 -#include -#else -#include -#endif - -namespace wpi { - -std::string SocketStrerror(int code) { -#ifdef _WIN32 - LPSTR errstr = nullptr; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - 0, code, 0, (LPSTR)&errstr, 0, 0); - std::string rv(errstr); - LocalFree(errstr); - return rv; -#else - return strerror(code); -#endif -} - -} // namespace wpi diff --git a/wpiutil/src/tcpsockets/TCPAcceptor.cpp b/wpiutil/src/tcpsockets/TCPAcceptor.cpp deleted file mode 100644 index db5d608..0000000 --- a/wpiutil/src/tcpsockets/TCPAcceptor.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - TCPAcceptor.cpp - - TCPAcceptor class definition. TCPAcceptor provides methods to passively - establish TCP/IP connections with clients. - - ------------------------------------------ - - Copyright © 2013 [Vic Hargrave - http://vichargrave.com] - - 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 "tcpsockets/TCPAcceptor.h" - -#include -#include -#ifdef _WIN32 -#include -#include -#pragma comment(lib, "Ws2_32.lib") -#else -#include -#include -#include -#include -#endif - -#include "llvm/SmallString.h" -#include "support/Logger.h" -#include "tcpsockets/SocketError.h" - -using namespace wpi; - -TCPAcceptor::TCPAcceptor(int port, const char* address, Logger& logger) - : m_lsd(0), - m_port(port), - m_address(address), - m_listening(false), - m_logger(logger) { - m_shutdown = false; -#ifdef _WIN32 - WSAData wsaData; - WORD wVersionRequested = MAKEWORD(2, 2); - WSAStartup(wVersionRequested, &wsaData); -#endif -} - -TCPAcceptor::~TCPAcceptor() { - if (m_lsd > 0) { - shutdown(); -#ifdef _WIN32 - closesocket(m_lsd); -#else - close(m_lsd); -#endif - } -#ifdef _WIN32 - WSACleanup(); -#endif -} - -int TCPAcceptor::start() { - if (m_listening) return 0; - - m_lsd = socket(PF_INET, SOCK_STREAM, 0); - if (m_lsd < 0) { - WPI_ERROR(m_logger, "could not create socket"); - return -1; - } - struct sockaddr_in address; - - std::memset(&address, 0, sizeof(address)); - address.sin_family = PF_INET; - if (m_address.size() > 0) { -#ifdef _WIN32 - llvm::SmallString<128> addr_copy(m_address); - addr_copy.push_back('\0'); - int res = InetPton(PF_INET, addr_copy.data(), &(address.sin_addr)); -#else - int res = inet_pton(PF_INET, m_address.c_str(), &(address.sin_addr)); -#endif - if (res != 1) { - WPI_ERROR(m_logger, "could not resolve " << m_address << " address"); - return -1; - } - } else { - address.sin_addr.s_addr = INADDR_ANY; - } - address.sin_port = htons(m_port); - - int optval = 1; - setsockopt(m_lsd, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof optval); - - int result = bind(m_lsd, (struct sockaddr*)&address, sizeof(address)); - if (result != 0) { - WPI_ERROR(m_logger, "bind() to port " << m_port - << " failed: " << SocketStrerror()); - return result; - } - - result = listen(m_lsd, 5); - if (result != 0) { - WPI_ERROR(m_logger, "listen() on port " << m_port - << " failed: " << SocketStrerror()); - return result; - } - m_listening = true; - return result; -} - -void TCPAcceptor::shutdown() { - m_shutdown = true; -#ifdef _WIN32 - ::shutdown(m_lsd, SD_BOTH); - - // this is ugly, but the easiest way to do this - // force wakeup of accept() with a non-blocking connect to ourselves - struct sockaddr_in address; - - std::memset(&address, 0, sizeof(address)); - address.sin_family = PF_INET; - llvm::SmallString<128> addr_copy; - if (m_address.size() > 0) - addr_copy = m_address; - else - addr_copy = "127.0.0.1"; - addr_copy.push_back('\0'); - int size = sizeof(address); - if (WSAStringToAddress(addr_copy.data(), PF_INET, nullptr, - (struct sockaddr*)&address, &size) != 0) - return; - address.sin_port = htons(m_port); - - fd_set sdset; - struct timeval tv; - int result = -1, valopt, sd = socket(AF_INET, SOCK_STREAM, 0); - if (sd < 0) return; - - // Set socket to non-blocking - u_long mode = 1; - ioctlsocket(sd, FIONBIO, &mode); - - // Try to connect - ::connect(sd, (struct sockaddr*)&address, sizeof(address)); - - // Close - ::closesocket(sd); - -#else - ::shutdown(m_lsd, SHUT_RDWR); - int nullfd = ::open("/dev/null", O_RDONLY); - if (nullfd >= 0) { - ::dup2(nullfd, m_lsd); - ::close(nullfd); - } -#endif -} - -std::unique_ptr TCPAcceptor::accept() { - if (!m_listening || m_shutdown) return nullptr; - - struct sockaddr_in address; -#ifdef _WIN32 - int len = sizeof(address); -#else - socklen_t len = sizeof(address); -#endif - std::memset(&address, 0, sizeof(address)); - int sd = ::accept(m_lsd, (struct sockaddr*)&address, &len); - if (sd < 0) { - if (!m_shutdown) - WPI_ERROR(m_logger, "accept() on port " - << m_port << " failed: " << SocketStrerror()); - return nullptr; - } - if (m_shutdown) { -#ifdef _WIN32 - closesocket(sd); -#else - close(sd); -#endif - return nullptr; - } - return std::unique_ptr(new TCPStream(sd, &address)); -} diff --git a/wpiutil/src/tcpsockets/TCPConnector.cpp b/wpiutil/src/tcpsockets/TCPConnector.cpp deleted file mode 100644 index ac563d1..0000000 --- a/wpiutil/src/tcpsockets/TCPConnector.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - TCPConnector.h - - TCPConnector class definition. TCPConnector provides methods to actively - establish TCP/IP connections with a server. - - ------------------------------------------ - - Copyright © 2013 [Vic Hargrave - http://vichargrave.com] - - 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 "tcpsockets/TCPConnector.h" - -#include -#include -#include -#include -#ifdef _WIN32 -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include "tcpsockets/TCPStream.h" - -#include "llvm/SmallString.h" -#include "support/Logger.h" -#include "tcpsockets/SocketError.h" - -using namespace wpi; - -static int ResolveHostName(const char* hostname, struct in_addr* addr) { - struct addrinfo hints; - struct addrinfo* res; - - hints.ai_flags = 0; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = 0; - hints.ai_addrlen = 0; - hints.ai_addr = nullptr; - hints.ai_canonname = nullptr; - hints.ai_next = nullptr; - int result = getaddrinfo(hostname, nullptr, &hints, &res); - if (result == 0) { - std::memcpy(addr, &((struct sockaddr_in*)res->ai_addr)->sin_addr, - sizeof(struct in_addr)); - freeaddrinfo(res); - } - return result; -} - -std::unique_ptr TCPConnector::connect(const char* server, - int port, Logger& logger, - int timeout) { -#ifdef _WIN32 - struct WSAHelper { - WSAHelper() { - WSAData wsaData; - WORD wVersionRequested = MAKEWORD(2, 2); - WSAStartup(wVersionRequested, &wsaData); - } - ~WSAHelper() { WSACleanup(); } - }; - static WSAHelper helper; -#endif - struct sockaddr_in address; - - std::memset(&address, 0, sizeof(address)); - address.sin_family = AF_INET; - if (ResolveHostName(server, &(address.sin_addr)) != 0) { -#ifdef _WIN32 - llvm::SmallString<128> addr_copy(server); - addr_copy.push_back('\0'); - int res = InetPton(PF_INET, addr_copy.data(), &(address.sin_addr)); -#else - int res = inet_pton(PF_INET, server, &(address.sin_addr)); -#endif - if (res != 1) { - WPI_ERROR(logger, "could not resolve " << server << " address"); - return nullptr; - } - } - address.sin_port = htons(port); - - if (timeout == 0) { - int sd = socket(AF_INET, SOCK_STREAM, 0); - if (sd < 0) { - WPI_ERROR(logger, "could not create socket"); - return nullptr; - } - if (::connect(sd, (struct sockaddr*)&address, sizeof(address)) != 0) { - WPI_ERROR(logger, "connect() to " << server << " port " << port << " failed: " << SocketStrerror()); -#ifdef _WIN32 - closesocket(sd); -#else - ::close(sd); -#endif - return nullptr; - } - return std::unique_ptr(new TCPStream(sd, &address)); - } - - fd_set sdset; - struct timeval tv; - socklen_t len; - int result = -1, valopt, sd = socket(AF_INET, SOCK_STREAM, 0); - if (sd < 0) { - WPI_ERROR(logger, "could not create socket"); - return nullptr; - } - - // Set socket to non-blocking -#ifdef _WIN32 - u_long mode = 1; - if (ioctlsocket(sd, FIONBIO, &mode) == SOCKET_ERROR) - WPI_WARNING(logger, - "could not set socket to non-blocking: " << SocketStrerror()); -#else - long arg; - arg = fcntl(sd, F_GETFL, nullptr); - if (arg < 0) { - WPI_WARNING(logger, - "could not set socket to non-blocking: " << SocketStrerror()); - } else { - arg |= O_NONBLOCK; - if (fcntl(sd, F_SETFL, arg) < 0) - WPI_WARNING(logger, - "could not set socket to non-blocking: " << SocketStrerror()); - } -#endif - - // Connect with time limit - if ((result = ::connect(sd, (struct sockaddr*)&address, sizeof(address))) < - 0) { - int my_errno = SocketErrno(); -#ifdef _WIN32 - if (my_errno == WSAEWOULDBLOCK || my_errno == WSAEINPROGRESS) { -#else - if (my_errno == EWOULDBLOCK || my_errno == EINPROGRESS) { -#endif - tv.tv_sec = timeout; - tv.tv_usec = 0; - FD_ZERO(&sdset); - FD_SET(sd, &sdset); - if (select(sd + 1, nullptr, &sdset, nullptr, &tv) > 0) { - len = sizeof(int); - getsockopt(sd, SOL_SOCKET, SO_ERROR, (char*)(&valopt), &len); - if (valopt) { - WPI_ERROR(logger, "select() to " << server << " port " << port << " error " << valopt << " - " << SocketStrerror(valopt)); - } - // connection established - else - result = 0; - } else - WPI_INFO(logger, "connect() to " << server << " port " << port << " timed out"); - } else - WPI_ERROR(logger, "connect() to " << server << " port " << port << " error " << SocketErrno() << " - " << SocketStrerror()); - } - - // Return socket to blocking mode -#ifdef _WIN32 - mode = 0; - if (ioctlsocket(sd, FIONBIO, &mode) == SOCKET_ERROR) - WPI_WARNING(logger, - "could not set socket to blocking: " << SocketStrerror()); -#else - arg = fcntl(sd, F_GETFL, nullptr); - if (arg < 0) { - WPI_WARNING(logger, - "could not set socket to blocking: " << SocketStrerror()); - } else { - arg &= (~O_NONBLOCK); - if (fcntl(sd, F_SETFL, arg) < 0) - WPI_WARNING(logger, - "could not set socket to blocking: " << SocketStrerror()); - } -#endif - - // Create stream object if connected, close if not. - if (result == -1) { -#ifdef _WIN32 - closesocket(sd); -#else - ::close(sd); -#endif - return nullptr; - } - return std::unique_ptr(new TCPStream(sd, &address)); -} diff --git a/wpiutil/src/tcpsockets/TCPStream.cpp b/wpiutil/src/tcpsockets/TCPStream.cpp deleted file mode 100644 index d738abe..0000000 --- a/wpiutil/src/tcpsockets/TCPStream.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - TCPStream.h - - TCPStream class definition. TCPStream provides methods to trasnfer - data between peers over a TCP/IP connection. - - ------------------------------------------ - - Copyright © 2013 [Vic Hargrave - http://vichargrave.com] - - 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 "tcpsockets/TCPStream.h" - -#include -#ifdef _WIN32 -#include -#include -#else -#include -#include -#include -#endif - -using namespace wpi; - -TCPStream::TCPStream(int sd, sockaddr_in* address) - : m_sd(sd), m_blocking(true) { - char ip[50]; -#ifdef _WIN32 - InetNtop(PF_INET, &(address->sin_addr.s_addr), ip, sizeof(ip) - 1); -#else - inet_ntop(PF_INET, (in_addr*)&(address->sin_addr.s_addr), ip, - sizeof(ip) - 1); -#ifdef SO_NOSIGPIPE - // disable SIGPIPE on Mac OS X - int set = 1; - setsockopt(m_sd, SOL_SOCKET, SO_NOSIGPIPE, (char*)&set, sizeof set); -#endif -#endif - m_peerIP = ip; - m_peerPort = ntohs(address->sin_port); -} - -TCPStream::~TCPStream() { close(); } - -std::size_t TCPStream::send(const char* buffer, std::size_t len, Error* err) { - if (m_sd < 0) { - *err = kConnectionClosed; - return 0; - } -#ifdef _WIN32 - WSABUF wsaBuf; - wsaBuf.buf = const_cast(buffer); - wsaBuf.len = (ULONG)len; - DWORD rv; - bool result = true; - while (WSASend(m_sd, &wsaBuf, 1, &rv, 0, nullptr, nullptr) == SOCKET_ERROR) { - if (WSAGetLastError() != WSAEWOULDBLOCK) { - result = false; - break; - } - if (!m_blocking) { - *err = kWouldBlock; - return 0; - } - Sleep(1); - } - if (!result) { - char Buffer[128]; -#ifdef _MSC_VER - sprintf_s(Buffer, "Send() failed: WSA error=%d\n", WSAGetLastError()); -#else - std::snprintf(Buffer, 128, "Send() failed: WSA error=%d\n", WSAGetLastError()); -#endif - OutputDebugStringA(Buffer); - *err = kConnectionReset; - return 0; - } -#else -#ifdef MSG_NOSIGNAL - // disable SIGPIPE on Linux - ssize_t rv = ::send(m_sd, buffer, len, MSG_NOSIGNAL); -#else - ssize_t rv = ::send(m_sd, buffer, len, 0); -#endif - if (rv < 0) { - if (!m_blocking && (errno == EAGAIN || errno == EWOULDBLOCK)) - *err = kWouldBlock; - else - *err = kConnectionReset; - return 0; - } -#endif - return static_cast(rv); -} - -std::size_t TCPStream::receive(char* buffer, std::size_t len, Error* err, - int timeout) { - if (m_sd < 0) { - *err = kConnectionClosed; - return 0; - } -#ifdef _WIN32 - int rv; -#else - ssize_t rv; -#endif - if (timeout <= 0) { -#ifdef _WIN32 - rv = recv(m_sd, buffer, len, 0); -#else - rv = read(m_sd, buffer, len); -#endif - } - else if (WaitForReadEvent(timeout)) { -#ifdef _WIN32 - rv = recv(m_sd, buffer, len, 0); -#else - rv = read(m_sd, buffer, len); -#endif - } else { - *err = kConnectionTimedOut; - return 0; - } - if (rv < 0) { -#ifdef _WIN32 - if (!m_blocking && WSAGetLastError() == WSAEWOULDBLOCK) -#else - if (!m_blocking && (errno == EAGAIN || errno == EWOULDBLOCK)) -#endif - *err = kWouldBlock; - else - *err = kConnectionReset; - return 0; - } - return static_cast(rv); -} - -void TCPStream::close() { - if (m_sd >= 0) { -#ifdef _WIN32 - ::shutdown(m_sd, SD_BOTH); - closesocket(m_sd); -#else - ::shutdown(m_sd, SHUT_RDWR); - ::close(m_sd); -#endif - } - m_sd = -1; -} - -llvm::StringRef TCPStream::getPeerIP() const { return m_peerIP; } - -int TCPStream::getPeerPort() const { return m_peerPort; } - -void TCPStream::setNoDelay() { - if (m_sd < 0) return; - int optval = 1; - setsockopt(m_sd, IPPROTO_TCP, TCP_NODELAY, (char*)&optval, sizeof optval); -} - -bool TCPStream::setBlocking(bool enabled) { - if (m_sd < 0) return true; // silently accept -#ifdef _WIN32 - u_long mode = enabled ? 0 : 1; - if (ioctlsocket(m_sd, FIONBIO, &mode) == SOCKET_ERROR) return false; -#else - long flags = fcntl(m_sd, F_GETFL, nullptr); - if (flags < 0) return false; - if (enabled) - flags &= ~O_NONBLOCK; - else - flags |= O_NONBLOCK; - if (fcntl(m_sd, F_SETFL, flags) < 0) return false; -#endif - return true; -} - -int TCPStream::getNativeHandle() const { - return m_sd; -} - -bool TCPStream::WaitForReadEvent(int timeout) { - fd_set sdset; - struct timeval tv; - - tv.tv_sec = timeout; - tv.tv_usec = 0; - FD_ZERO(&sdset); - FD_SET(m_sd, &sdset); - if (select(m_sd + 1, &sdset, NULL, NULL, &tv) > 0) { - return true; - } - return false; -} diff --git a/wpiutil/unittest/Base64Test.cpp b/wpiutil/unittest/Base64Test.cpp deleted file mode 100644 index 972ca48..0000000 --- a/wpiutil/unittest/Base64Test.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#include "support/Base64.h" - -#include "gtest/gtest.h" - -namespace wpi { - -struct Base64TestParam { - int plain_len; - const char* plain; - const char* encoded; -}; - -std::ostream& operator<<(std::ostream& os, const Base64TestParam& param) { - os << "Base64TestParam(Len: " << param.plain_len << ", " - << "Plain: \"" << param.plain << "\", " - << "Encoded: \"" << param.encoded << "\")"; - return os; -} - -class Base64Test : public ::testing::TestWithParam { - protected: - llvm::StringRef GetPlain() { - if (GetParam().plain_len < 0) - return llvm::StringRef(GetParam().plain); - else - return llvm::StringRef(GetParam().plain, GetParam().plain_len); - } -}; - -TEST_P(Base64Test, Encode) { - std::string s; - Base64Encode(GetPlain(), &s); - ASSERT_EQ(GetParam().encoded, s); -} - -TEST_P(Base64Test, Decode) { - std::string s; - llvm::StringRef encoded = GetParam().encoded; - EXPECT_EQ(encoded.size(), Base64Decode(encoded, &s)); - ASSERT_EQ(GetPlain(), s); -} - -static Base64TestParam sample[] = { - {-1, "Send reinforcements", "U2VuZCByZWluZm9yY2VtZW50cw=="}, - {-1, "Now is the time for all good coders\n to learn C++", - "Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKIHRvIGxlYXJuIEMrKw=="}, - {-1, - "This is line one\nThis is line two\nThis is line three\nAnd so on...\n", - "VGhpcyBpcyBsaW5lIG9uZQpUaGlzIGlzIGxpbmUgdHdvClRoaXMgaXMgbGluZSB0aHJlZQpBb" - "mQgc28gb24uLi4K"}, -}; - -INSTANTIATE_TEST_CASE_P(Base64Sample, Base64Test, ::testing::ValuesIn(sample)); - -static Base64TestParam standard[] = { - {0, "", ""}, - {1, "\0", "AA=="}, - {2, "\0\0", "AAA="}, - {3, "\0\0\0", "AAAA"}, - {1, "\377", "/w=="}, - {2, "\377\377", "//8="}, - {3, "\377\377\377", "////"}, - {2, "\xff\xef", "/+8="}, -}; - -INSTANTIATE_TEST_CASE_P(Base64Standard, Base64Test, - ::testing::ValuesIn(standard)); - -} // namespace wpi diff --git a/wpiutil/unittest/leb128Test.cpp b/wpiutil/unittest/leb128Test.cpp deleted file mode 100644 index 00a79ee..0000000 --- a/wpiutil/unittest/leb128Test.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -//===- llvm/unittest/Support/LEB128Test.cpp - LEB128 function tests -------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "support/leb128.h" - -#include "gtest/gtest.h" - -#include -#include - -#include "llvm/SmallString.h" -#include "llvm/StringRef.h" - -#include "support/raw_istream.h" - -namespace wpi { - -TEST(LEB128Test, WriteUleb128) { -#define EXPECT_ULEB128_EQ(EXPECTED, VALUE, PAD) \ - do { \ - llvm::StringRef expected(EXPECTED, sizeof(EXPECTED)-1); \ - llvm::SmallString<32> buf; \ - std::size_t size = WriteUleb128(buf, VALUE); \ - EXPECT_EQ(size, buf.size()); \ - EXPECT_EQ(expected, buf.str()); \ - } while (0) - - // Write ULEB128 - EXPECT_ULEB128_EQ("\x00", 0, 0); - EXPECT_ULEB128_EQ("\x01", 1, 0); - EXPECT_ULEB128_EQ("\x3f", 63, 0); - EXPECT_ULEB128_EQ("\x40", 64, 0); - EXPECT_ULEB128_EQ("\x7f", 0x7f, 0); - EXPECT_ULEB128_EQ("\x80\x01", 0x80, 0); - EXPECT_ULEB128_EQ("\x81\x01", 0x81, 0); - EXPECT_ULEB128_EQ("\x90\x01", 0x90, 0); - EXPECT_ULEB128_EQ("\xff\x01", 0xff, 0); - EXPECT_ULEB128_EQ("\x80\x02", 0x100, 0); - EXPECT_ULEB128_EQ("\x81\x02", 0x101, 0); - -#undef EXPECT_ULEB128_EQ -} - -TEST(LEB128Test, ReadUleb128) { -#define EXPECT_READ_ULEB128_EQ(EXPECTED, VALUE) \ - do { \ - unsigned long val = 0; \ - std::size_t size = ReadUleb128(VALUE, &val); \ - EXPECT_EQ(sizeof(VALUE) - 1, size); \ - EXPECT_EQ(EXPECTED, val); \ - } while (0) - - // Read ULEB128 - EXPECT_READ_ULEB128_EQ(0u, "\x00"); - EXPECT_READ_ULEB128_EQ(1u, "\x01"); - EXPECT_READ_ULEB128_EQ(63u, "\x3f"); - EXPECT_READ_ULEB128_EQ(64u, "\x40"); - EXPECT_READ_ULEB128_EQ(0x7fu, "\x7f"); - EXPECT_READ_ULEB128_EQ(0x80u, "\x80\x01"); - EXPECT_READ_ULEB128_EQ(0x81u, "\x81\x01"); - EXPECT_READ_ULEB128_EQ(0x90u, "\x90\x01"); - EXPECT_READ_ULEB128_EQ(0xffu, "\xff\x01"); - EXPECT_READ_ULEB128_EQ(0x100u, "\x80\x02"); - EXPECT_READ_ULEB128_EQ(0x101u, "\x81\x02"); - EXPECT_READ_ULEB128_EQ(8320u, "\x80\xc1\x80\x80\x10"); - -#undef EXPECT_READ_ULEB128_EQ -} - -TEST(LEB128Test, SizeUleb128) { - // Testing Plan: - // (1) 128 ^ n ............ need (n+1) bytes - // (2) 128 ^ n * 64 ....... need (n+1) bytes - // (3) 128 ^ (n+1) - 1 .... need (n+1) bytes - - EXPECT_EQ(1u, SizeUleb128(0)); // special case - - EXPECT_EQ(1u, SizeUleb128(0x1UL)); - EXPECT_EQ(1u, SizeUleb128(0x40UL)); - EXPECT_EQ(1u, SizeUleb128(0x7fUL)); - - EXPECT_EQ(2u, SizeUleb128(0x80UL)); - EXPECT_EQ(2u, SizeUleb128(0x2000UL)); - EXPECT_EQ(2u, SizeUleb128(0x3fffUL)); - - EXPECT_EQ(3u, SizeUleb128(0x4000UL)); - EXPECT_EQ(3u, SizeUleb128(0x100000UL)); - EXPECT_EQ(3u, SizeUleb128(0x1fffffUL)); - - EXPECT_EQ(4u, SizeUleb128(0x200000UL)); - EXPECT_EQ(4u, SizeUleb128(0x8000000UL)); - EXPECT_EQ(4u, SizeUleb128(0xfffffffUL)); - - EXPECT_EQ(5u, SizeUleb128(0x10000000UL)); - EXPECT_EQ(5u, SizeUleb128(0x40000000UL)); - EXPECT_EQ(5u, SizeUleb128(0x7fffffffUL)); - - EXPECT_EQ(5u, SizeUleb128(UINT32_MAX)); -} - -} // namespace wpi diff --git a/wpiutil/unittest/main.cpp b/wpiutil/unittest/main.cpp deleted file mode 100644 index e380efd..0000000 --- a/wpiutil/unittest/main.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2015. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#include "gtest/gtest.h" - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} diff --git a/wpiutil/unittest/unittest.gradle b/wpiutil/unittest/unittest.gradle deleted file mode 100644 index 89fc290..0000000 --- a/wpiutil/unittest/unittest.gradle +++ /dev/null @@ -1,39 +0,0 @@ -apply plugin: 'google-test' - -model { - testSuites { - wpiutilTest { - sources { - cpp { - source { - srcDirs = ["${rootDir}/wpiutil/unittest"] - includes = ['**/*.cpp'] - } - exportedHeaders { - srcDirs = ["${rootDir}/wpiutil/include", "${rootDir}/gmock/include", "${rootDir}/gmock/gtest/include"] - includes = ['**/*.h'] - } - } - } - binaries.all { - lib project: ':gmock', library: 'gmock', linkage: 'static' - lib library: 'wpiutil', linkage: 'static' - } - } - } -} - -model { - binaries { - withType(GoogleTestTestSuiteBinarySpec) { - lib project: ':gmock', library: "gmock", linkage: "static" - lib library: 'wpiutil', linkage: 'static' - if (targetPlatform.operatingSystem.windows) { - cppCompiler.args '/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS' - } else { - cppCompiler.args '-pthread', '-std=c++1y' - linker.args '-pthread' - } - } - } -}