Commit a8acebb0 by Heitbrink, David A

Initial version of this lib

parents
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- Backup*.rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
\ No newline at end of file
/*
WARNING: THIS FILE IS AUTO-GENERATED. DO NOT MODIFY.
This file was generated from NADS.idl using "rtiddsgen".
The rtiddsgen tool is part of the RTI Connext distribution.
For more information, type 'rtiddsgen -help' at a command shell
or consult the RTI Connext manual.
*/
#include <iosfwd>
#include <iomanip>
#include "rti/topic/cdr/Serialization.hpp"
#include "NADS.hpp"
#include "NADSPlugin.hpp"
#include <rti/util/ostream_operators.hpp>
// ---- TypeInt:
TypeInt::TypeInt() :
m_eid_ (0) {
}
TypeInt::TypeInt (
const rti::core::bounded_sequence<int32_t, 256>& data,
int32_t eid)
:
m_data_( data ),
m_eid_( eid ) {
}
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifdef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeInt::TypeInt(TypeInt&& other_) OMG_NOEXCEPT :m_data_ (std::move(other_.m_data_))
,
m_eid_ (std::move(other_.m_eid_))
{
}
TypeInt& TypeInt::operator=(TypeInt&& other_) OMG_NOEXCEPT {
TypeInt tmp(std::move(other_));
swap(tmp);
return *this;
}
#endif
#endif
void TypeInt::swap(TypeInt& other_) OMG_NOEXCEPT
{
using std::swap;
swap(m_data_, other_.m_data_);
swap(m_eid_, other_.m_eid_);
}
bool TypeInt::operator == (const TypeInt& other_) const {
if (m_data_ != other_.m_data_) {
return false;
}
if (m_eid_ != other_.m_eid_) {
return false;
}
return true;
}
bool TypeInt::operator != (const TypeInt& other_) const {
return !this->operator ==(other_);
}
// --- Getters and Setters: -------------------------------------------------
rti::core::bounded_sequence<int32_t, 256>& TypeInt::data() OMG_NOEXCEPT {
return m_data_;
}
const rti::core::bounded_sequence<int32_t, 256>& TypeInt::data() const OMG_NOEXCEPT {
return m_data_;
}
void TypeInt::data(const rti::core::bounded_sequence<int32_t, 256>& value) {
m_data_ = value;
}
int32_t& TypeInt::eid() OMG_NOEXCEPT {
return m_eid_;
}
const int32_t& TypeInt::eid() const OMG_NOEXCEPT {
return m_eid_;
}
void TypeInt::eid(int32_t value) {
m_eid_ = value;
}
std::ostream& operator << (std::ostream& o,const TypeInt& sample)
{
rti::util::StreamFlagSaver flag_saver (o);
o <<"[";
o << "data: " << sample.data()<<", ";
o << "eid: " << sample.eid() ;
o <<"]";
return o;
}
// ---- TypeFloat:
TypeFloat::TypeFloat() :
m_eid_ (0) {
}
TypeFloat::TypeFloat (
const rti::core::bounded_sequence<float, 256>& data,
int32_t eid)
:
m_data_( data ),
m_eid_( eid ) {
}
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifdef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeFloat::TypeFloat(TypeFloat&& other_) OMG_NOEXCEPT :m_data_ (std::move(other_.m_data_))
,
m_eid_ (std::move(other_.m_eid_))
{
}
TypeFloat& TypeFloat::operator=(TypeFloat&& other_) OMG_NOEXCEPT {
TypeFloat tmp(std::move(other_));
swap(tmp);
return *this;
}
#endif
#endif
void TypeFloat::swap(TypeFloat& other_) OMG_NOEXCEPT
{
using std::swap;
swap(m_data_, other_.m_data_);
swap(m_eid_, other_.m_eid_);
}
bool TypeFloat::operator == (const TypeFloat& other_) const {
if (m_data_ != other_.m_data_) {
return false;
}
if (m_eid_ != other_.m_eid_) {
return false;
}
return true;
}
bool TypeFloat::operator != (const TypeFloat& other_) const {
return !this->operator ==(other_);
}
// --- Getters and Setters: -------------------------------------------------
rti::core::bounded_sequence<float, 256>& TypeFloat::data() OMG_NOEXCEPT {
return m_data_;
}
const rti::core::bounded_sequence<float, 256>& TypeFloat::data() const OMG_NOEXCEPT {
return m_data_;
}
void TypeFloat::data(const rti::core::bounded_sequence<float, 256>& value) {
m_data_ = value;
}
int32_t& TypeFloat::eid() OMG_NOEXCEPT {
return m_eid_;
}
const int32_t& TypeFloat::eid() const OMG_NOEXCEPT {
return m_eid_;
}
void TypeFloat::eid(int32_t value) {
m_eid_ = value;
}
std::ostream& operator << (std::ostream& o,const TypeFloat& sample)
{
rti::util::StreamFlagSaver flag_saver (o);
o <<"[";
o << "data: " << sample.data()<<", ";
o << "eid: " << sample.eid() ;
o <<"]";
return o;
}
// ---- TypeDouble:
TypeDouble::TypeDouble() :
m_eid_ (0) {
}
TypeDouble::TypeDouble (
const rti::core::bounded_sequence<double, 256>& data,
int32_t eid)
:
m_data_( data ),
m_eid_( eid ) {
}
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifdef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeDouble::TypeDouble(TypeDouble&& other_) OMG_NOEXCEPT :m_data_ (std::move(other_.m_data_))
,
m_eid_ (std::move(other_.m_eid_))
{
}
TypeDouble& TypeDouble::operator=(TypeDouble&& other_) OMG_NOEXCEPT {
TypeDouble tmp(std::move(other_));
swap(tmp);
return *this;
}
#endif
#endif
void TypeDouble::swap(TypeDouble& other_) OMG_NOEXCEPT
{
using std::swap;
swap(m_data_, other_.m_data_);
swap(m_eid_, other_.m_eid_);
}
bool TypeDouble::operator == (const TypeDouble& other_) const {
if (m_data_ != other_.m_data_) {
return false;
}
if (m_eid_ != other_.m_eid_) {
return false;
}
return true;
}
bool TypeDouble::operator != (const TypeDouble& other_) const {
return !this->operator ==(other_);
}
// --- Getters and Setters: -------------------------------------------------
rti::core::bounded_sequence<double, 256>& TypeDouble::data() OMG_NOEXCEPT {
return m_data_;
}
const rti::core::bounded_sequence<double, 256>& TypeDouble::data() const OMG_NOEXCEPT {
return m_data_;
}
void TypeDouble::data(const rti::core::bounded_sequence<double, 256>& value) {
m_data_ = value;
}
int32_t& TypeDouble::eid() OMG_NOEXCEPT {
return m_eid_;
}
const int32_t& TypeDouble::eid() const OMG_NOEXCEPT {
return m_eid_;
}
void TypeDouble::eid(int32_t value) {
m_eid_ = value;
}
std::ostream& operator << (std::ostream& o,const TypeDouble& sample)
{
rti::util::StreamFlagSaver flag_saver (o);
o <<"[";
o << "data: " << sample.data()<<", ";
o << "eid: " << sample.eid() ;
o <<"]";
return o;
}
// ---- TypeShort:
TypeShort::TypeShort() :
m_eid_ (0) {
}
TypeShort::TypeShort (
const rti::core::bounded_sequence<int16_t, 256>& data,
int32_t eid)
:
m_data_( data ),
m_eid_( eid ) {
}
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifdef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeShort::TypeShort(TypeShort&& other_) OMG_NOEXCEPT :m_data_ (std::move(other_.m_data_))
,
m_eid_ (std::move(other_.m_eid_))
{
}
TypeShort& TypeShort::operator=(TypeShort&& other_) OMG_NOEXCEPT {
TypeShort tmp(std::move(other_));
swap(tmp);
return *this;
}
#endif
#endif
void TypeShort::swap(TypeShort& other_) OMG_NOEXCEPT
{
using std::swap;
swap(m_data_, other_.m_data_);
swap(m_eid_, other_.m_eid_);
}
bool TypeShort::operator == (const TypeShort& other_) const {
if (m_data_ != other_.m_data_) {
return false;
}
if (m_eid_ != other_.m_eid_) {
return false;
}
return true;
}
bool TypeShort::operator != (const TypeShort& other_) const {
return !this->operator ==(other_);
}
// --- Getters and Setters: -------------------------------------------------
rti::core::bounded_sequence<int16_t, 256>& TypeShort::data() OMG_NOEXCEPT {
return m_data_;
}
const rti::core::bounded_sequence<int16_t, 256>& TypeShort::data() const OMG_NOEXCEPT {
return m_data_;
}
void TypeShort::data(const rti::core::bounded_sequence<int16_t, 256>& value) {
m_data_ = value;
}
int32_t& TypeShort::eid() OMG_NOEXCEPT {
return m_eid_;
}
const int32_t& TypeShort::eid() const OMG_NOEXCEPT {
return m_eid_;
}
void TypeShort::eid(int32_t value) {
m_eid_ = value;
}
std::ostream& operator << (std::ostream& o,const TypeShort& sample)
{
rti::util::StreamFlagSaver flag_saver (o);
o <<"[";
o << "data: " << sample.data()<<", ";
o << "eid: " << sample.eid() ;
o <<"]";
return o;
}
// ---- TypeChar:
TypeChar::TypeChar() :
m_eid_ (0) {
}
TypeChar::TypeChar (
const std::string& data,
int32_t eid)
:
m_data_( data ),
m_eid_( eid ) {
}
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifdef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeChar::TypeChar(TypeChar&& other_) OMG_NOEXCEPT :m_data_ (std::move(other_.m_data_))
,
m_eid_ (std::move(other_.m_eid_))
{
}
TypeChar& TypeChar::operator=(TypeChar&& other_) OMG_NOEXCEPT {
TypeChar tmp(std::move(other_));
swap(tmp);
return *this;
}
#endif
#endif
void TypeChar::swap(TypeChar& other_) OMG_NOEXCEPT
{
using std::swap;
swap(m_data_, other_.m_data_);
swap(m_eid_, other_.m_eid_);
}
bool TypeChar::operator == (const TypeChar& other_) const {
if (m_data_ != other_.m_data_) {
return false;
}
if (m_eid_ != other_.m_eid_) {
return false;
}
return true;
}
bool TypeChar::operator != (const TypeChar& other_) const {
return !this->operator ==(other_);
}
// --- Getters and Setters: -------------------------------------------------
std::string& TypeChar::data() OMG_NOEXCEPT {
return m_data_;
}
const std::string& TypeChar::data() const OMG_NOEXCEPT {
return m_data_;
}
void TypeChar::data(const std::string& value) {
m_data_ = value;
}
int32_t& TypeChar::eid() OMG_NOEXCEPT {
return m_eid_;
}
const int32_t& TypeChar::eid() const OMG_NOEXCEPT {
return m_eid_;
}
void TypeChar::eid(int32_t value) {
m_eid_ = value;
}
std::ostream& operator << (std::ostream& o,const TypeChar& sample)
{
rti::util::StreamFlagSaver flag_saver (o);
o <<"[";
o << "data: " << sample.data()<<", ";
o << "eid: " << sample.eid() ;
o <<"]";
return o;
}
// --- Type traits: -------------------------------------------------
namespace rti {
namespace topic {
template<>
struct native_type_code<TypeInt> {
static DDS_TypeCode * get()
{
static RTIBool is_initialized = RTI_FALSE;
static DDS_TypeCode TypeInt_g_tc_data_sequence = DDS_INITIALIZE_SEQUENCE_TYPECODE((256),NULL);
static DDS_TypeCode_Member TypeInt_g_tc_members[2]=
{
{
(char *)"data",/* Member name */
{
0,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
},
{
(char *)"eid",/* Member name */
{
1,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
}
};
static DDS_TypeCode TypeInt_g_tc =
{{
DDS_TK_STRUCT,/* Kind */
DDS_BOOLEAN_FALSE, /* Ignored */
-1, /*Ignored*/
(char *)"TypeInt", /* Name */
NULL, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
2, /* Number of members */
TypeInt_g_tc_members, /* Members */
DDS_VM_NONE /* Ignored */
}}; /* Type code for TypeInt*/
if (is_initialized) {
return &TypeInt_g_tc;
}
TypeInt_g_tc_data_sequence._data._typeCode = (RTICdrTypeCode *)&DDS_g_tc_long;
TypeInt_g_tc_members[0]._representation._typeCode = (RTICdrTypeCode *)& TypeInt_g_tc_data_sequence;
TypeInt_g_tc_members[1]._representation._typeCode = (RTICdrTypeCode *)&DDS_g_tc_long;
is_initialized = RTI_TRUE;
return &TypeInt_g_tc;
}
}; // native_type_code
const dds::core::xtypes::StructType& dynamic_type<TypeInt>::get()
{
return static_cast<const dds::core::xtypes::StructType&>(
rti::core::native_conversions::cast_from_native<dds::core::xtypes::DynamicType>(
*(native_type_code<TypeInt>::get())));
}
template<>
struct native_type_code<TypeFloat> {
static DDS_TypeCode * get()
{
static RTIBool is_initialized = RTI_FALSE;
static DDS_TypeCode TypeFloat_g_tc_data_sequence = DDS_INITIALIZE_SEQUENCE_TYPECODE((256),NULL);
static DDS_TypeCode_Member TypeFloat_g_tc_members[2]=
{
{
(char *)"data",/* Member name */
{
0,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
},
{
(char *)"eid",/* Member name */
{
1,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
}
};
static DDS_TypeCode TypeFloat_g_tc =
{{
DDS_TK_STRUCT,/* Kind */
DDS_BOOLEAN_FALSE, /* Ignored */
-1, /*Ignored*/
(char *)"TypeFloat", /* Name */
NULL, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
2, /* Number of members */
TypeFloat_g_tc_members, /* Members */
DDS_VM_NONE /* Ignored */
}}; /* Type code for TypeFloat*/
if (is_initialized) {
return &TypeFloat_g_tc;
}
TypeFloat_g_tc_data_sequence._data._typeCode = (RTICdrTypeCode *)&DDS_g_tc_float;
TypeFloat_g_tc_members[0]._representation._typeCode = (RTICdrTypeCode *)& TypeFloat_g_tc_data_sequence;
TypeFloat_g_tc_members[1]._representation._typeCode = (RTICdrTypeCode *)&DDS_g_tc_long;
is_initialized = RTI_TRUE;
return &TypeFloat_g_tc;
}
}; // native_type_code
const dds::core::xtypes::StructType& dynamic_type<TypeFloat>::get()
{
return static_cast<const dds::core::xtypes::StructType&>(
rti::core::native_conversions::cast_from_native<dds::core::xtypes::DynamicType>(
*(native_type_code<TypeFloat>::get())));
}
template<>
struct native_type_code<TypeDouble> {
static DDS_TypeCode * get()
{
static RTIBool is_initialized = RTI_FALSE;
static DDS_TypeCode TypeDouble_g_tc_data_sequence = DDS_INITIALIZE_SEQUENCE_TYPECODE((256),NULL);
static DDS_TypeCode_Member TypeDouble_g_tc_members[2]=
{
{
(char *)"data",/* Member name */
{
0,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
},
{
(char *)"eid",/* Member name */
{
1,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
}
};
static DDS_TypeCode TypeDouble_g_tc =
{{
DDS_TK_STRUCT,/* Kind */
DDS_BOOLEAN_FALSE, /* Ignored */
-1, /*Ignored*/
(char *)"TypeDouble", /* Name */
NULL, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
2, /* Number of members */
TypeDouble_g_tc_members, /* Members */
DDS_VM_NONE /* Ignored */
}}; /* Type code for TypeDouble*/
if (is_initialized) {
return &TypeDouble_g_tc;
}
TypeDouble_g_tc_data_sequence._data._typeCode = (RTICdrTypeCode *)&DDS_g_tc_double;
TypeDouble_g_tc_members[0]._representation._typeCode = (RTICdrTypeCode *)& TypeDouble_g_tc_data_sequence;
TypeDouble_g_tc_members[1]._representation._typeCode = (RTICdrTypeCode *)&DDS_g_tc_long;
is_initialized = RTI_TRUE;
return &TypeDouble_g_tc;
}
}; // native_type_code
const dds::core::xtypes::StructType& dynamic_type<TypeDouble>::get()
{
return static_cast<const dds::core::xtypes::StructType&>(
rti::core::native_conversions::cast_from_native<dds::core::xtypes::DynamicType>(
*(native_type_code<TypeDouble>::get())));
}
template<>
struct native_type_code<TypeShort> {
static DDS_TypeCode * get()
{
static RTIBool is_initialized = RTI_FALSE;
static DDS_TypeCode TypeShort_g_tc_data_sequence = DDS_INITIALIZE_SEQUENCE_TYPECODE((256),NULL);
static DDS_TypeCode_Member TypeShort_g_tc_members[2]=
{
{
(char *)"data",/* Member name */
{
0,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
},
{
(char *)"eid",/* Member name */
{
1,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
}
};
static DDS_TypeCode TypeShort_g_tc =
{{
DDS_TK_STRUCT,/* Kind */
DDS_BOOLEAN_FALSE, /* Ignored */
-1, /*Ignored*/
(char *)"TypeShort", /* Name */
NULL, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
2, /* Number of members */
TypeShort_g_tc_members, /* Members */
DDS_VM_NONE /* Ignored */
}}; /* Type code for TypeShort*/
if (is_initialized) {
return &TypeShort_g_tc;
}
TypeShort_g_tc_data_sequence._data._typeCode = (RTICdrTypeCode *)&DDS_g_tc_short;
TypeShort_g_tc_members[0]._representation._typeCode = (RTICdrTypeCode *)& TypeShort_g_tc_data_sequence;
TypeShort_g_tc_members[1]._representation._typeCode = (RTICdrTypeCode *)&DDS_g_tc_long;
is_initialized = RTI_TRUE;
return &TypeShort_g_tc;
}
}; // native_type_code
const dds::core::xtypes::StructType& dynamic_type<TypeShort>::get()
{
return static_cast<const dds::core::xtypes::StructType&>(
rti::core::native_conversions::cast_from_native<dds::core::xtypes::DynamicType>(
*(native_type_code<TypeShort>::get())));
}
template<>
struct native_type_code<TypeChar> {
static DDS_TypeCode * get()
{
static RTIBool is_initialized = RTI_FALSE;
static DDS_TypeCode TypeChar_g_tc_data_string = DDS_INITIALIZE_STRING_TYPECODE((512));
static DDS_TypeCode_Member TypeChar_g_tc_members[2]=
{
{
(char *)"data",/* Member name */
{
0,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
},
{
(char *)"eid",/* Member name */
{
1,/* Representation ID */
DDS_BOOLEAN_FALSE,/* Is a pointer? */
-1, /* Bitfield bits */
NULL/* Member type code is assigned later */
},
0, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
RTI_CDR_REQUIRED_MEMBER, /* Is a key? */
DDS_PUBLIC_MEMBER,/* Member visibility */
1,
NULL/* Ignored */
}
};
static DDS_TypeCode TypeChar_g_tc =
{{
DDS_TK_STRUCT,/* Kind */
DDS_BOOLEAN_FALSE, /* Ignored */
-1, /*Ignored*/
(char *)"TypeChar", /* Name */
NULL, /* Ignored */
0, /* Ignored */
0, /* Ignored */
NULL, /* Ignored */
2, /* Number of members */
TypeChar_g_tc_members, /* Members */
DDS_VM_NONE /* Ignored */
}}; /* Type code for TypeChar*/
if (is_initialized) {
return &TypeChar_g_tc;
}
TypeChar_g_tc_members[0]._representation._typeCode = (RTICdrTypeCode *)&TypeChar_g_tc_data_string;
TypeChar_g_tc_members[1]._representation._typeCode = (RTICdrTypeCode *)&DDS_g_tc_long;
is_initialized = RTI_TRUE;
return &TypeChar_g_tc;
}
}; // native_type_code
const dds::core::xtypes::StructType& dynamic_type<TypeChar>::get()
{
return static_cast<const dds::core::xtypes::StructType&>(
rti::core::native_conversions::cast_from_native<dds::core::xtypes::DynamicType>(
*(native_type_code<TypeChar>::get())));
}
}
}
namespace dds {
namespace topic {
void topic_type_support<TypeInt>:: register_type(
dds::domain::DomainParticipant& participant,
const std::string& type_name)
{
rti::domain::register_type_plugin(
participant,
type_name,
TypeIntPlugin_new,
TypeIntPlugin_delete);
}
std::vector<char>& topic_type_support<TypeInt>::to_cdr_buffer(
std::vector<char>& buffer, const TypeInt& sample)
{
// First get the length of the buffer
unsigned int length = 0;
RTIBool ok = TypeIntPlugin_serialize_to_cdr_buffer(
NULL,
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to calculate cdr buffer size");
// Create a vector with that size and copy the cdr buffer into it
buffer.resize(length);
ok = TypeIntPlugin_serialize_to_cdr_buffer(
&buffer[0],
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to copy cdr buffer");
return buffer;
}
void topic_type_support<TypeInt>::from_cdr_buffer(TypeInt& sample,
const std::vector<char>& buffer)
{
RTIBool ok = TypeIntPlugin_deserialize_from_cdr_buffer(
&sample,
&buffer[0],
static_cast<unsigned int>(buffer.size()));
rti::core::check_return_code(ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to create TypeInt from cdr buffer");
}
void topic_type_support<TypeInt>::reset_sample(TypeInt& sample)
{
rti::topic::reset_sample(sample.data());
rti::topic::reset_sample(sample.eid());
}
void topic_type_support<TypeInt>::allocate_sample(TypeInt& sample, int, int)
{
rti::topic::allocate_sample(sample.data(), 256, -1);
}
void topic_type_support<TypeFloat>:: register_type(
dds::domain::DomainParticipant& participant,
const std::string& type_name)
{
rti::domain::register_type_plugin(
participant,
type_name,
TypeFloatPlugin_new,
TypeFloatPlugin_delete);
}
std::vector<char>& topic_type_support<TypeFloat>::to_cdr_buffer(
std::vector<char>& buffer, const TypeFloat& sample)
{
// First get the length of the buffer
unsigned int length = 0;
RTIBool ok = TypeFloatPlugin_serialize_to_cdr_buffer(
NULL,
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to calculate cdr buffer size");
// Create a vector with that size and copy the cdr buffer into it
buffer.resize(length);
ok = TypeFloatPlugin_serialize_to_cdr_buffer(
&buffer[0],
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to copy cdr buffer");
return buffer;
}
void topic_type_support<TypeFloat>::from_cdr_buffer(TypeFloat& sample,
const std::vector<char>& buffer)
{
RTIBool ok = TypeFloatPlugin_deserialize_from_cdr_buffer(
&sample,
&buffer[0],
static_cast<unsigned int>(buffer.size()));
rti::core::check_return_code(ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to create TypeFloat from cdr buffer");
}
void topic_type_support<TypeFloat>::reset_sample(TypeFloat& sample)
{
rti::topic::reset_sample(sample.data());
rti::topic::reset_sample(sample.eid());
}
void topic_type_support<TypeFloat>::allocate_sample(TypeFloat& sample, int, int)
{
rti::topic::allocate_sample(sample.data(), 256, -1);
}
void topic_type_support<TypeDouble>:: register_type(
dds::domain::DomainParticipant& participant,
const std::string& type_name)
{
rti::domain::register_type_plugin(
participant,
type_name,
TypeDoublePlugin_new,
TypeDoublePlugin_delete);
}
std::vector<char>& topic_type_support<TypeDouble>::to_cdr_buffer(
std::vector<char>& buffer, const TypeDouble& sample)
{
// First get the length of the buffer
unsigned int length = 0;
RTIBool ok = TypeDoublePlugin_serialize_to_cdr_buffer(
NULL,
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to calculate cdr buffer size");
// Create a vector with that size and copy the cdr buffer into it
buffer.resize(length);
ok = TypeDoublePlugin_serialize_to_cdr_buffer(
&buffer[0],
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to copy cdr buffer");
return buffer;
}
void topic_type_support<TypeDouble>::from_cdr_buffer(TypeDouble& sample,
const std::vector<char>& buffer)
{
RTIBool ok = TypeDoublePlugin_deserialize_from_cdr_buffer(
&sample,
&buffer[0],
static_cast<unsigned int>(buffer.size()));
rti::core::check_return_code(ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to create TypeDouble from cdr buffer");
}
void topic_type_support<TypeDouble>::reset_sample(TypeDouble& sample)
{
rti::topic::reset_sample(sample.data());
rti::topic::reset_sample(sample.eid());
}
void topic_type_support<TypeDouble>::allocate_sample(TypeDouble& sample, int, int)
{
rti::topic::allocate_sample(sample.data(), 256, -1);
}
void topic_type_support<TypeShort>:: register_type(
dds::domain::DomainParticipant& participant,
const std::string& type_name)
{
rti::domain::register_type_plugin(
participant,
type_name,
TypeShortPlugin_new,
TypeShortPlugin_delete);
}
std::vector<char>& topic_type_support<TypeShort>::to_cdr_buffer(
std::vector<char>& buffer, const TypeShort& sample)
{
// First get the length of the buffer
unsigned int length = 0;
RTIBool ok = TypeShortPlugin_serialize_to_cdr_buffer(
NULL,
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to calculate cdr buffer size");
// Create a vector with that size and copy the cdr buffer into it
buffer.resize(length);
ok = TypeShortPlugin_serialize_to_cdr_buffer(
&buffer[0],
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to copy cdr buffer");
return buffer;
}
void topic_type_support<TypeShort>::from_cdr_buffer(TypeShort& sample,
const std::vector<char>& buffer)
{
RTIBool ok = TypeShortPlugin_deserialize_from_cdr_buffer(
&sample,
&buffer[0],
static_cast<unsigned int>(buffer.size()));
rti::core::check_return_code(ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to create TypeShort from cdr buffer");
}
void topic_type_support<TypeShort>::reset_sample(TypeShort& sample)
{
rti::topic::reset_sample(sample.data());
rti::topic::reset_sample(sample.eid());
}
void topic_type_support<TypeShort>::allocate_sample(TypeShort& sample, int, int)
{
rti::topic::allocate_sample(sample.data(), 256, -1);
}
void topic_type_support<TypeChar>:: register_type(
dds::domain::DomainParticipant& participant,
const std::string& type_name)
{
rti::domain::register_type_plugin(
participant,
type_name,
TypeCharPlugin_new,
TypeCharPlugin_delete);
}
std::vector<char>& topic_type_support<TypeChar>::to_cdr_buffer(
std::vector<char>& buffer, const TypeChar& sample)
{
// First get the length of the buffer
unsigned int length = 0;
RTIBool ok = TypeCharPlugin_serialize_to_cdr_buffer(
NULL,
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to calculate cdr buffer size");
// Create a vector with that size and copy the cdr buffer into it
buffer.resize(length);
ok = TypeCharPlugin_serialize_to_cdr_buffer(
&buffer[0],
&length,
&sample);
rti::core::check_return_code(
ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to copy cdr buffer");
return buffer;
}
void topic_type_support<TypeChar>::from_cdr_buffer(TypeChar& sample,
const std::vector<char>& buffer)
{
RTIBool ok = TypeCharPlugin_deserialize_from_cdr_buffer(
&sample,
&buffer[0],
static_cast<unsigned int>(buffer.size()));
rti::core::check_return_code(ok ? DDS_RETCODE_OK : DDS_RETCODE_ERROR,
"Failed to create TypeChar from cdr buffer");
}
void topic_type_support<TypeChar>::reset_sample(TypeChar& sample)
{
rti::topic::reset_sample(sample.data());
rti::topic::reset_sample(sample.eid());
}
void topic_type_support<TypeChar>::allocate_sample(TypeChar& sample, int, int)
{
rti::topic::allocate_sample(sample.data(), -1, 512);
}
}
}
/*
WARNING: THIS FILE IS AUTO-GENERATED. DO NOT MODIFY.
This file was generated from NADS.idl using "rtiddsgen".
The rtiddsgen tool is part of the RTI Connext distribution.
For more information, type 'rtiddsgen -help' at a command shell
or consult the RTI Connext manual.
*/
#ifndef NADS_1916641539_hpp
#define NADS_1916641539_hpp
#include <iosfwd>
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
/* If the code is building on Windows, start exporting symbols.
*/
#undef RTIUSERDllExport
#define RTIUSERDllExport __declspec(dllexport)
#endif
#include "dds/domain/DomainParticipant.hpp"
#include "dds/topic/TopicTraits.hpp"
#include "dds/core/SafeEnumeration.hpp"
#include "dds/core/String.hpp"
#include "dds/core/array.hpp"
#include "dds/core/vector.hpp"
#include "dds/core/Optional.hpp"
#include "dds/core/xtypes/DynamicType.hpp"
#include "dds/core/xtypes/StructType.hpp"
#include "dds/core/xtypes/UnionType.hpp"
#include "dds/core/xtypes/EnumType.hpp"
#include "dds/core/xtypes/AliasType.hpp"
#include "rti/core/array.hpp"
#include "rti/core/BoundedSequence.hpp"
#include "rti/util/StreamFlagSaver.hpp"
#include "rti/domain/PluginSupport.hpp"
#include "rti/core/LongDouble.hpp"
#include "dds/core/External.hpp"
#include "rti/core/Pointer.hpp"
#include "rti/topic/TopicTraits.hpp"
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
/* If the code is building on Windows, stop exporting symbols.
*/
#undef RTIUSERDllExport
#define RTIUSERDllExport
#endif
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
/* If the code is building on Windows, start exporting symbols.
*/
#undef NDDSUSERDllExport
#define NDDSUSERDllExport __declspec(dllexport)
#endif
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
// On Windows, dll-export template instantiations of standard types used by
// other dll-exported types
template class NDDSUSERDllExport std::allocator<int32_t>;
template class NDDSUSERDllExport std::vector<int32_t >;
#endif
class NDDSUSERDllExport TypeInt {
public:
TypeInt();
TypeInt(
const rti::core::bounded_sequence<int32_t, 256>& data,
int32_t eid);
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifndef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeInt (TypeInt&&) = default;
TypeInt& operator=(TypeInt&&) = default;
TypeInt& operator=(const TypeInt&) = default;
TypeInt(const TypeInt&) = default;
#else
TypeInt(TypeInt&& other_) OMG_NOEXCEPT;
TypeInt& operator=(TypeInt&& other_) OMG_NOEXCEPT;
#endif
#endif
rti::core::bounded_sequence<int32_t, 256>& data() OMG_NOEXCEPT;
const rti::core::bounded_sequence<int32_t, 256>& data() const OMG_NOEXCEPT;
void data(const rti::core::bounded_sequence<int32_t, 256>& value);
int32_t& eid() OMG_NOEXCEPT;
const int32_t& eid() const OMG_NOEXCEPT;
void eid(int32_t value);
bool operator == (const TypeInt& other_) const;
bool operator != (const TypeInt& other_) const;
void swap(TypeInt& other_) OMG_NOEXCEPT ;
private:
rti::core::bounded_sequence<int32_t, 256> m_data_;
int32_t m_eid_;
};
inline void swap(TypeInt& a, TypeInt& b) OMG_NOEXCEPT
{
a.swap(b);
}
NDDSUSERDllExport std::ostream& operator<<(std::ostream& o, const TypeInt& sample);
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
// On Windows, dll-export template instantiations of standard types used by
// other dll-exported types
template class NDDSUSERDllExport std::allocator<float>;
template class NDDSUSERDllExport std::vector<float >;
#endif
class NDDSUSERDllExport TypeFloat {
public:
TypeFloat();
TypeFloat(
const rti::core::bounded_sequence<float, 256>& data,
int32_t eid);
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifndef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeFloat (TypeFloat&&) = default;
TypeFloat& operator=(TypeFloat&&) = default;
TypeFloat& operator=(const TypeFloat&) = default;
TypeFloat(const TypeFloat&) = default;
#else
TypeFloat(TypeFloat&& other_) OMG_NOEXCEPT;
TypeFloat& operator=(TypeFloat&& other_) OMG_NOEXCEPT;
#endif
#endif
rti::core::bounded_sequence<float, 256>& data() OMG_NOEXCEPT;
const rti::core::bounded_sequence<float, 256>& data() const OMG_NOEXCEPT;
void data(const rti::core::bounded_sequence<float, 256>& value);
int32_t& eid() OMG_NOEXCEPT;
const int32_t& eid() const OMG_NOEXCEPT;
void eid(int32_t value);
bool operator == (const TypeFloat& other_) const;
bool operator != (const TypeFloat& other_) const;
void swap(TypeFloat& other_) OMG_NOEXCEPT ;
private:
rti::core::bounded_sequence<float, 256> m_data_;
int32_t m_eid_;
};
inline void swap(TypeFloat& a, TypeFloat& b) OMG_NOEXCEPT
{
a.swap(b);
}
NDDSUSERDllExport std::ostream& operator<<(std::ostream& o, const TypeFloat& sample);
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
// On Windows, dll-export template instantiations of standard types used by
// other dll-exported types
template class NDDSUSERDllExport std::allocator<double>;
template class NDDSUSERDllExport std::vector<double >;
#endif
class NDDSUSERDllExport TypeDouble {
public:
TypeDouble();
TypeDouble(
const rti::core::bounded_sequence<double, 256>& data,
int32_t eid);
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifndef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeDouble (TypeDouble&&) = default;
TypeDouble& operator=(TypeDouble&&) = default;
TypeDouble& operator=(const TypeDouble&) = default;
TypeDouble(const TypeDouble&) = default;
#else
TypeDouble(TypeDouble&& other_) OMG_NOEXCEPT;
TypeDouble& operator=(TypeDouble&& other_) OMG_NOEXCEPT;
#endif
#endif
rti::core::bounded_sequence<double, 256>& data() OMG_NOEXCEPT;
const rti::core::bounded_sequence<double, 256>& data() const OMG_NOEXCEPT;
void data(const rti::core::bounded_sequence<double, 256>& value);
int32_t& eid() OMG_NOEXCEPT;
const int32_t& eid() const OMG_NOEXCEPT;
void eid(int32_t value);
bool operator == (const TypeDouble& other_) const;
bool operator != (const TypeDouble& other_) const;
void swap(TypeDouble& other_) OMG_NOEXCEPT ;
private:
rti::core::bounded_sequence<double, 256> m_data_;
int32_t m_eid_;
};
inline void swap(TypeDouble& a, TypeDouble& b) OMG_NOEXCEPT
{
a.swap(b);
}
NDDSUSERDllExport std::ostream& operator<<(std::ostream& o, const TypeDouble& sample);
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
// On Windows, dll-export template instantiations of standard types used by
// other dll-exported types
template class NDDSUSERDllExport std::allocator<int16_t>;
template class NDDSUSERDllExport std::vector<int16_t >;
#endif
class NDDSUSERDllExport TypeShort {
public:
TypeShort();
TypeShort(
const rti::core::bounded_sequence<int16_t, 256>& data,
int32_t eid);
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifndef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeShort (TypeShort&&) = default;
TypeShort& operator=(TypeShort&&) = default;
TypeShort& operator=(const TypeShort&) = default;
TypeShort(const TypeShort&) = default;
#else
TypeShort(TypeShort&& other_) OMG_NOEXCEPT;
TypeShort& operator=(TypeShort&& other_) OMG_NOEXCEPT;
#endif
#endif
rti::core::bounded_sequence<int16_t, 256>& data() OMG_NOEXCEPT;
const rti::core::bounded_sequence<int16_t, 256>& data() const OMG_NOEXCEPT;
void data(const rti::core::bounded_sequence<int16_t, 256>& value);
int32_t& eid() OMG_NOEXCEPT;
const int32_t& eid() const OMG_NOEXCEPT;
void eid(int32_t value);
bool operator == (const TypeShort& other_) const;
bool operator != (const TypeShort& other_) const;
void swap(TypeShort& other_) OMG_NOEXCEPT ;
private:
rti::core::bounded_sequence<int16_t, 256> m_data_;
int32_t m_eid_;
};
inline void swap(TypeShort& a, TypeShort& b) OMG_NOEXCEPT
{
a.swap(b);
}
NDDSUSERDllExport std::ostream& operator<<(std::ostream& o, const TypeShort& sample);
class NDDSUSERDllExport TypeChar {
public:
TypeChar();
TypeChar(
const std::string& data,
int32_t eid);
#ifdef RTI_CXX11_RVALUE_REFERENCES
#ifndef RTI_CXX11_NO_IMPLICIT_MOVE_OPERATIONS
TypeChar (TypeChar&&) = default;
TypeChar& operator=(TypeChar&&) = default;
TypeChar& operator=(const TypeChar&) = default;
TypeChar(const TypeChar&) = default;
#else
TypeChar(TypeChar&& other_) OMG_NOEXCEPT;
TypeChar& operator=(TypeChar&& other_) OMG_NOEXCEPT;
#endif
#endif
std::string& data() OMG_NOEXCEPT;
const std::string& data() const OMG_NOEXCEPT;
void data(const std::string& value);
int32_t& eid() OMG_NOEXCEPT;
const int32_t& eid() const OMG_NOEXCEPT;
void eid(int32_t value);
bool operator == (const TypeChar& other_) const;
bool operator != (const TypeChar& other_) const;
void swap(TypeChar& other_) OMG_NOEXCEPT ;
private:
std::string m_data_;
int32_t m_eid_;
};
inline void swap(TypeChar& a, TypeChar& b) OMG_NOEXCEPT
{
a.swap(b);
}
NDDSUSERDllExport std::ostream& operator<<(std::ostream& o, const TypeChar& sample);
namespace dds {
namespace topic {
template<>
struct topic_type_name<TypeInt> {
NDDSUSERDllExport static std::string value() {
return "TypeInt";
}
};
template<>
struct is_topic_type<TypeInt> : public dds::core::true_type {};
template<>
struct topic_type_support<TypeInt> {
NDDSUSERDllExport
static void register_type(
dds::domain::DomainParticipant& participant,
const std::string & type_name);
NDDSUSERDllExport
static std::vector<char>& to_cdr_buffer(
std::vector<char>& buffer, const TypeInt& sample);
NDDSUSERDllExport
static void from_cdr_buffer(TypeInt& sample, const std::vector<char>& buffer);
NDDSUSERDllExport
static void reset_sample(TypeInt& sample);
NDDSUSERDllExport
static void allocate_sample(TypeInt& sample, int, int);
static const rti::topic::TypePluginKind::type type_plugin_kind =
rti::topic::TypePluginKind::STL;
};
template<>
struct topic_type_name<TypeFloat> {
NDDSUSERDllExport static std::string value() {
return "TypeFloat";
}
};
template<>
struct is_topic_type<TypeFloat> : public dds::core::true_type {};
template<>
struct topic_type_support<TypeFloat> {
NDDSUSERDllExport
static void register_type(
dds::domain::DomainParticipant& participant,
const std::string & type_name);
NDDSUSERDllExport
static std::vector<char>& to_cdr_buffer(
std::vector<char>& buffer, const TypeFloat& sample);
NDDSUSERDllExport
static void from_cdr_buffer(TypeFloat& sample, const std::vector<char>& buffer);
NDDSUSERDllExport
static void reset_sample(TypeFloat& sample);
NDDSUSERDllExport
static void allocate_sample(TypeFloat& sample, int, int);
static const rti::topic::TypePluginKind::type type_plugin_kind =
rti::topic::TypePluginKind::STL;
};
template<>
struct topic_type_name<TypeDouble> {
NDDSUSERDllExport static std::string value() {
return "TypeDouble";
}
};
template<>
struct is_topic_type<TypeDouble> : public dds::core::true_type {};
template<>
struct topic_type_support<TypeDouble> {
NDDSUSERDllExport
static void register_type(
dds::domain::DomainParticipant& participant,
const std::string & type_name);
NDDSUSERDllExport
static std::vector<char>& to_cdr_buffer(
std::vector<char>& buffer, const TypeDouble& sample);
NDDSUSERDllExport
static void from_cdr_buffer(TypeDouble& sample, const std::vector<char>& buffer);
NDDSUSERDllExport
static void reset_sample(TypeDouble& sample);
NDDSUSERDllExport
static void allocate_sample(TypeDouble& sample, int, int);
static const rti::topic::TypePluginKind::type type_plugin_kind =
rti::topic::TypePluginKind::STL;
};
template<>
struct topic_type_name<TypeShort> {
NDDSUSERDllExport static std::string value() {
return "TypeShort";
}
};
template<>
struct is_topic_type<TypeShort> : public dds::core::true_type {};
template<>
struct topic_type_support<TypeShort> {
NDDSUSERDllExport
static void register_type(
dds::domain::DomainParticipant& participant,
const std::string & type_name);
NDDSUSERDllExport
static std::vector<char>& to_cdr_buffer(
std::vector<char>& buffer, const TypeShort& sample);
NDDSUSERDllExport
static void from_cdr_buffer(TypeShort& sample, const std::vector<char>& buffer);
NDDSUSERDllExport
static void reset_sample(TypeShort& sample);
NDDSUSERDllExport
static void allocate_sample(TypeShort& sample, int, int);
static const rti::topic::TypePluginKind::type type_plugin_kind =
rti::topic::TypePluginKind::STL;
};
template<>
struct topic_type_name<TypeChar> {
NDDSUSERDllExport static std::string value() {
return "TypeChar";
}
};
template<>
struct is_topic_type<TypeChar> : public dds::core::true_type {};
template<>
struct topic_type_support<TypeChar> {
NDDSUSERDllExport
static void register_type(
dds::domain::DomainParticipant& participant,
const std::string & type_name);
NDDSUSERDllExport
static std::vector<char>& to_cdr_buffer(
std::vector<char>& buffer, const TypeChar& sample);
NDDSUSERDllExport
static void from_cdr_buffer(TypeChar& sample, const std::vector<char>& buffer);
NDDSUSERDllExport
static void reset_sample(TypeChar& sample);
NDDSUSERDllExport
static void allocate_sample(TypeChar& sample, int, int);
static const rti::topic::TypePluginKind::type type_plugin_kind =
rti::topic::TypePluginKind::STL;
};
}
}
namespace rti {
namespace topic {
template<>
struct dynamic_type<TypeInt> {
typedef dds::core::xtypes::StructType type;
NDDSUSERDllExport static const dds::core::xtypes::StructType& get();
};
template <>
struct extensibility<TypeInt> {
static const dds::core::xtypes::ExtensibilityKind::type kind =
dds::core::xtypes::ExtensibilityKind::EXTENSIBLE;
};
template<>
struct dynamic_type<TypeFloat> {
typedef dds::core::xtypes::StructType type;
NDDSUSERDllExport static const dds::core::xtypes::StructType& get();
};
template <>
struct extensibility<TypeFloat> {
static const dds::core::xtypes::ExtensibilityKind::type kind =
dds::core::xtypes::ExtensibilityKind::EXTENSIBLE;
};
template<>
struct dynamic_type<TypeDouble> {
typedef dds::core::xtypes::StructType type;
NDDSUSERDllExport static const dds::core::xtypes::StructType& get();
};
template <>
struct extensibility<TypeDouble> {
static const dds::core::xtypes::ExtensibilityKind::type kind =
dds::core::xtypes::ExtensibilityKind::EXTENSIBLE;
};
template<>
struct dynamic_type<TypeShort> {
typedef dds::core::xtypes::StructType type;
NDDSUSERDllExport static const dds::core::xtypes::StructType& get();
};
template <>
struct extensibility<TypeShort> {
static const dds::core::xtypes::ExtensibilityKind::type kind =
dds::core::xtypes::ExtensibilityKind::EXTENSIBLE;
};
template<>
struct dynamic_type<TypeChar> {
typedef dds::core::xtypes::StructType type;
NDDSUSERDllExport static const dds::core::xtypes::StructType& get();
};
template <>
struct extensibility<TypeChar> {
static const dds::core::xtypes::ExtensibilityKind::type kind =
dds::core::xtypes::ExtensibilityKind::EXTENSIBLE;
};
}
}
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
/* If the code is building on Windows, stop exporting symbols.
*/
#undef NDDSUSERDllExport
#define NDDSUSERDllExport
#endif
#endif // NADS_1916641539_hpp
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
WARNING: THIS FILE IS AUTO-GENERATED. DO NOT MODIFY.
This file was generated from NADS.idl using "rtiddsgen".
The rtiddsgen tool is part of the RTI Connext distribution.
For more information, type 'rtiddsgen -help' at a command shell
or consult the RTI Connext manual.
*/
#ifndef NADSPlugin_1916641539_h
#define NADSPlugin_1916641539_h
#include "NADS.hpp"
struct RTICdrStream;
#ifndef pres_typePlugin_h
#include "pres/pres_typePlugin.h"
#endif
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
/* If the code is building on Windows, start exporting symbols.
*/
#undef NDDSUSERDllExport
#define NDDSUSERDllExport __declspec(dllexport)
#endif
#define TypeIntPlugin_get_sample PRESTypePluginDefaultEndpointData_getSample
#define TypeIntPlugin_get_buffer PRESTypePluginDefaultEndpointData_getBuffer
#define TypeIntPlugin_return_buffer PRESTypePluginDefaultEndpointData_returnBuffer
#define TypeIntPlugin_create_sample PRESTypePluginDefaultEndpointData_createSample
#define TypeIntPlugin_destroy_sample PRESTypePluginDefaultEndpointData_deleteSample
/* --------------------------------------------------------------------------------------
Support functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern TypeInt*
TypeIntPluginSupport_create_data_w_params(
const struct DDS_TypeAllocationParams_t * alloc_params);
NDDSUSERDllExport extern TypeInt*
TypeIntPluginSupport_create_data_ex(RTIBool allocate_pointers);
NDDSUSERDllExport extern TypeInt*
TypeIntPluginSupport_create_data(void);
NDDSUSERDllExport extern RTIBool
TypeIntPluginSupport_copy_data(
TypeInt *out,
const TypeInt *in);
NDDSUSERDllExport extern void
TypeIntPluginSupport_destroy_data_w_params(
TypeInt *sample,
const struct DDS_TypeDeallocationParams_t * dealloc_params);
NDDSUSERDllExport extern void
TypeIntPluginSupport_destroy_data_ex(
TypeInt *sample,RTIBool deallocate_pointers);
NDDSUSERDllExport extern void
TypeIntPluginSupport_destroy_data(
TypeInt *sample);
NDDSUSERDllExport extern void
TypeIntPluginSupport_print_data(
const TypeInt *sample,
const char *desc,
unsigned int indent);
/* ----------------------------------------------------------------------------
Callback functions:
* ---------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginParticipantData
TypeIntPlugin_on_participant_attached(
void *registration_data,
const struct PRESTypePluginParticipantInfo *participant_info,
RTIBool top_level_registration,
void *container_plugin_context,
RTICdrTypeCode *typeCode);
NDDSUSERDllExport extern void
TypeIntPlugin_on_participant_detached(
PRESTypePluginParticipantData participant_data);
NDDSUSERDllExport extern PRESTypePluginEndpointData
TypeIntPlugin_on_endpoint_attached(
PRESTypePluginParticipantData participant_data,
const struct PRESTypePluginEndpointInfo *endpoint_info,
RTIBool top_level_registration,
void *container_plugin_context);
NDDSUSERDllExport extern void
TypeIntPlugin_on_endpoint_detached(
PRESTypePluginEndpointData endpoint_data);
NDDSUSERDllExport extern void
TypeIntPlugin_return_sample(
PRESTypePluginEndpointData endpoint_data,
TypeInt *sample,
void *handle);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_copy_sample(
PRESTypePluginEndpointData endpoint_data,
TypeInt *out,
const TypeInt *in);
/* ----------------------------------------------------------------------------
(De)Serialize functions:
* ------------------------------------------------------------------------- */
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_serialize(
PRESTypePluginEndpointData endpoint_data,
const TypeInt *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_deserialize_sample(
PRESTypePluginEndpointData endpoint_data,
TypeInt *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_serialize_to_cdr_buffer(
char * buffer,
unsigned int * length,
const TypeInt *sample);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_deserialize(
PRESTypePluginEndpointData endpoint_data,
TypeInt **sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_deserialize_from_cdr_buffer(
TypeInt *sample,
const char * buffer,
unsigned int length);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_skip(
PRESTypePluginEndpointData endpoint_data,
struct RTICdrStream *stream,
RTIBool skip_encapsulation,
RTIBool skip_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern unsigned int
TypeIntPlugin_get_serialized_sample_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeIntPlugin_get_serialized_sample_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeIntPlugin_get_serialized_sample_min_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeIntPlugin_get_serialized_sample_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment,
const TypeInt * sample);
/* --------------------------------------------------------------------------------------
Key Management functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginKeyKind
TypeIntPlugin_get_key_kind(void);
NDDSUSERDllExport extern unsigned int
TypeIntPlugin_get_serialized_key_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeIntPlugin_get_serialized_key_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_serialize_key(
PRESTypePluginEndpointData endpoint_data,
const TypeInt *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_deserialize_key_sample(
PRESTypePluginEndpointData endpoint_data,
TypeInt * sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_deserialize_key(
PRESTypePluginEndpointData endpoint_data,
TypeInt ** sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeIntPlugin_serialized_sample_to_key(
PRESTypePluginEndpointData endpoint_data,
TypeInt *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
/* Plugin Functions */
NDDSUSERDllExport extern struct PRESTypePlugin*
TypeIntPlugin_new(void);
NDDSUSERDllExport extern void
TypeIntPlugin_delete(struct PRESTypePlugin *);
#define TypeFloatPlugin_get_sample PRESTypePluginDefaultEndpointData_getSample
#define TypeFloatPlugin_get_buffer PRESTypePluginDefaultEndpointData_getBuffer
#define TypeFloatPlugin_return_buffer PRESTypePluginDefaultEndpointData_returnBuffer
#define TypeFloatPlugin_create_sample PRESTypePluginDefaultEndpointData_createSample
#define TypeFloatPlugin_destroy_sample PRESTypePluginDefaultEndpointData_deleteSample
/* --------------------------------------------------------------------------------------
Support functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern TypeFloat*
TypeFloatPluginSupport_create_data_w_params(
const struct DDS_TypeAllocationParams_t * alloc_params);
NDDSUSERDllExport extern TypeFloat*
TypeFloatPluginSupport_create_data_ex(RTIBool allocate_pointers);
NDDSUSERDllExport extern TypeFloat*
TypeFloatPluginSupport_create_data(void);
NDDSUSERDllExport extern RTIBool
TypeFloatPluginSupport_copy_data(
TypeFloat *out,
const TypeFloat *in);
NDDSUSERDllExport extern void
TypeFloatPluginSupport_destroy_data_w_params(
TypeFloat *sample,
const struct DDS_TypeDeallocationParams_t * dealloc_params);
NDDSUSERDllExport extern void
TypeFloatPluginSupport_destroy_data_ex(
TypeFloat *sample,RTIBool deallocate_pointers);
NDDSUSERDllExport extern void
TypeFloatPluginSupport_destroy_data(
TypeFloat *sample);
NDDSUSERDllExport extern void
TypeFloatPluginSupport_print_data(
const TypeFloat *sample,
const char *desc,
unsigned int indent);
/* ----------------------------------------------------------------------------
Callback functions:
* ---------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginParticipantData
TypeFloatPlugin_on_participant_attached(
void *registration_data,
const struct PRESTypePluginParticipantInfo *participant_info,
RTIBool top_level_registration,
void *container_plugin_context,
RTICdrTypeCode *typeCode);
NDDSUSERDllExport extern void
TypeFloatPlugin_on_participant_detached(
PRESTypePluginParticipantData participant_data);
NDDSUSERDllExport extern PRESTypePluginEndpointData
TypeFloatPlugin_on_endpoint_attached(
PRESTypePluginParticipantData participant_data,
const struct PRESTypePluginEndpointInfo *endpoint_info,
RTIBool top_level_registration,
void *container_plugin_context);
NDDSUSERDllExport extern void
TypeFloatPlugin_on_endpoint_detached(
PRESTypePluginEndpointData endpoint_data);
NDDSUSERDllExport extern void
TypeFloatPlugin_return_sample(
PRESTypePluginEndpointData endpoint_data,
TypeFloat *sample,
void *handle);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_copy_sample(
PRESTypePluginEndpointData endpoint_data,
TypeFloat *out,
const TypeFloat *in);
/* ----------------------------------------------------------------------------
(De)Serialize functions:
* ------------------------------------------------------------------------- */
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_serialize(
PRESTypePluginEndpointData endpoint_data,
const TypeFloat *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_deserialize_sample(
PRESTypePluginEndpointData endpoint_data,
TypeFloat *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_serialize_to_cdr_buffer(
char * buffer,
unsigned int * length,
const TypeFloat *sample);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_deserialize(
PRESTypePluginEndpointData endpoint_data,
TypeFloat **sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_deserialize_from_cdr_buffer(
TypeFloat *sample,
const char * buffer,
unsigned int length);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_skip(
PRESTypePluginEndpointData endpoint_data,
struct RTICdrStream *stream,
RTIBool skip_encapsulation,
RTIBool skip_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern unsigned int
TypeFloatPlugin_get_serialized_sample_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeFloatPlugin_get_serialized_sample_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeFloatPlugin_get_serialized_sample_min_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeFloatPlugin_get_serialized_sample_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment,
const TypeFloat * sample);
/* --------------------------------------------------------------------------------------
Key Management functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginKeyKind
TypeFloatPlugin_get_key_kind(void);
NDDSUSERDllExport extern unsigned int
TypeFloatPlugin_get_serialized_key_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeFloatPlugin_get_serialized_key_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_serialize_key(
PRESTypePluginEndpointData endpoint_data,
const TypeFloat *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_deserialize_key_sample(
PRESTypePluginEndpointData endpoint_data,
TypeFloat * sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_deserialize_key(
PRESTypePluginEndpointData endpoint_data,
TypeFloat ** sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeFloatPlugin_serialized_sample_to_key(
PRESTypePluginEndpointData endpoint_data,
TypeFloat *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
/* Plugin Functions */
NDDSUSERDllExport extern struct PRESTypePlugin*
TypeFloatPlugin_new(void);
NDDSUSERDllExport extern void
TypeFloatPlugin_delete(struct PRESTypePlugin *);
#define TypeDoublePlugin_get_sample PRESTypePluginDefaultEndpointData_getSample
#define TypeDoublePlugin_get_buffer PRESTypePluginDefaultEndpointData_getBuffer
#define TypeDoublePlugin_return_buffer PRESTypePluginDefaultEndpointData_returnBuffer
#define TypeDoublePlugin_create_sample PRESTypePluginDefaultEndpointData_createSample
#define TypeDoublePlugin_destroy_sample PRESTypePluginDefaultEndpointData_deleteSample
/* --------------------------------------------------------------------------------------
Support functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern TypeDouble*
TypeDoublePluginSupport_create_data_w_params(
const struct DDS_TypeAllocationParams_t * alloc_params);
NDDSUSERDllExport extern TypeDouble*
TypeDoublePluginSupport_create_data_ex(RTIBool allocate_pointers);
NDDSUSERDllExport extern TypeDouble*
TypeDoublePluginSupport_create_data(void);
NDDSUSERDllExport extern RTIBool
TypeDoublePluginSupport_copy_data(
TypeDouble *out,
const TypeDouble *in);
NDDSUSERDllExport extern void
TypeDoublePluginSupport_destroy_data_w_params(
TypeDouble *sample,
const struct DDS_TypeDeallocationParams_t * dealloc_params);
NDDSUSERDllExport extern void
TypeDoublePluginSupport_destroy_data_ex(
TypeDouble *sample,RTIBool deallocate_pointers);
NDDSUSERDllExport extern void
TypeDoublePluginSupport_destroy_data(
TypeDouble *sample);
NDDSUSERDllExport extern void
TypeDoublePluginSupport_print_data(
const TypeDouble *sample,
const char *desc,
unsigned int indent);
/* ----------------------------------------------------------------------------
Callback functions:
* ---------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginParticipantData
TypeDoublePlugin_on_participant_attached(
void *registration_data,
const struct PRESTypePluginParticipantInfo *participant_info,
RTIBool top_level_registration,
void *container_plugin_context,
RTICdrTypeCode *typeCode);
NDDSUSERDllExport extern void
TypeDoublePlugin_on_participant_detached(
PRESTypePluginParticipantData participant_data);
NDDSUSERDllExport extern PRESTypePluginEndpointData
TypeDoublePlugin_on_endpoint_attached(
PRESTypePluginParticipantData participant_data,
const struct PRESTypePluginEndpointInfo *endpoint_info,
RTIBool top_level_registration,
void *container_plugin_context);
NDDSUSERDllExport extern void
TypeDoublePlugin_on_endpoint_detached(
PRESTypePluginEndpointData endpoint_data);
NDDSUSERDllExport extern void
TypeDoublePlugin_return_sample(
PRESTypePluginEndpointData endpoint_data,
TypeDouble *sample,
void *handle);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_copy_sample(
PRESTypePluginEndpointData endpoint_data,
TypeDouble *out,
const TypeDouble *in);
/* ----------------------------------------------------------------------------
(De)Serialize functions:
* ------------------------------------------------------------------------- */
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_serialize(
PRESTypePluginEndpointData endpoint_data,
const TypeDouble *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_deserialize_sample(
PRESTypePluginEndpointData endpoint_data,
TypeDouble *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_serialize_to_cdr_buffer(
char * buffer,
unsigned int * length,
const TypeDouble *sample);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_deserialize(
PRESTypePluginEndpointData endpoint_data,
TypeDouble **sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_deserialize_from_cdr_buffer(
TypeDouble *sample,
const char * buffer,
unsigned int length);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_skip(
PRESTypePluginEndpointData endpoint_data,
struct RTICdrStream *stream,
RTIBool skip_encapsulation,
RTIBool skip_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern unsigned int
TypeDoublePlugin_get_serialized_sample_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeDoublePlugin_get_serialized_sample_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeDoublePlugin_get_serialized_sample_min_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeDoublePlugin_get_serialized_sample_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment,
const TypeDouble * sample);
/* --------------------------------------------------------------------------------------
Key Management functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginKeyKind
TypeDoublePlugin_get_key_kind(void);
NDDSUSERDllExport extern unsigned int
TypeDoublePlugin_get_serialized_key_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeDoublePlugin_get_serialized_key_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_serialize_key(
PRESTypePluginEndpointData endpoint_data,
const TypeDouble *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_deserialize_key_sample(
PRESTypePluginEndpointData endpoint_data,
TypeDouble * sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_deserialize_key(
PRESTypePluginEndpointData endpoint_data,
TypeDouble ** sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeDoublePlugin_serialized_sample_to_key(
PRESTypePluginEndpointData endpoint_data,
TypeDouble *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
/* Plugin Functions */
NDDSUSERDllExport extern struct PRESTypePlugin*
TypeDoublePlugin_new(void);
NDDSUSERDllExport extern void
TypeDoublePlugin_delete(struct PRESTypePlugin *);
#define TypeShortPlugin_get_sample PRESTypePluginDefaultEndpointData_getSample
#define TypeShortPlugin_get_buffer PRESTypePluginDefaultEndpointData_getBuffer
#define TypeShortPlugin_return_buffer PRESTypePluginDefaultEndpointData_returnBuffer
#define TypeShortPlugin_create_sample PRESTypePluginDefaultEndpointData_createSample
#define TypeShortPlugin_destroy_sample PRESTypePluginDefaultEndpointData_deleteSample
/* --------------------------------------------------------------------------------------
Support functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern TypeShort*
TypeShortPluginSupport_create_data_w_params(
const struct DDS_TypeAllocationParams_t * alloc_params);
NDDSUSERDllExport extern TypeShort*
TypeShortPluginSupport_create_data_ex(RTIBool allocate_pointers);
NDDSUSERDllExport extern TypeShort*
TypeShortPluginSupport_create_data(void);
NDDSUSERDllExport extern RTIBool
TypeShortPluginSupport_copy_data(
TypeShort *out,
const TypeShort *in);
NDDSUSERDllExport extern void
TypeShortPluginSupport_destroy_data_w_params(
TypeShort *sample,
const struct DDS_TypeDeallocationParams_t * dealloc_params);
NDDSUSERDllExport extern void
TypeShortPluginSupport_destroy_data_ex(
TypeShort *sample,RTIBool deallocate_pointers);
NDDSUSERDllExport extern void
TypeShortPluginSupport_destroy_data(
TypeShort *sample);
NDDSUSERDllExport extern void
TypeShortPluginSupport_print_data(
const TypeShort *sample,
const char *desc,
unsigned int indent);
/* ----------------------------------------------------------------------------
Callback functions:
* ---------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginParticipantData
TypeShortPlugin_on_participant_attached(
void *registration_data,
const struct PRESTypePluginParticipantInfo *participant_info,
RTIBool top_level_registration,
void *container_plugin_context,
RTICdrTypeCode *typeCode);
NDDSUSERDllExport extern void
TypeShortPlugin_on_participant_detached(
PRESTypePluginParticipantData participant_data);
NDDSUSERDllExport extern PRESTypePluginEndpointData
TypeShortPlugin_on_endpoint_attached(
PRESTypePluginParticipantData participant_data,
const struct PRESTypePluginEndpointInfo *endpoint_info,
RTIBool top_level_registration,
void *container_plugin_context);
NDDSUSERDllExport extern void
TypeShortPlugin_on_endpoint_detached(
PRESTypePluginEndpointData endpoint_data);
NDDSUSERDllExport extern void
TypeShortPlugin_return_sample(
PRESTypePluginEndpointData endpoint_data,
TypeShort *sample,
void *handle);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_copy_sample(
PRESTypePluginEndpointData endpoint_data,
TypeShort *out,
const TypeShort *in);
/* ----------------------------------------------------------------------------
(De)Serialize functions:
* ------------------------------------------------------------------------- */
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_serialize(
PRESTypePluginEndpointData endpoint_data,
const TypeShort *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_deserialize_sample(
PRESTypePluginEndpointData endpoint_data,
TypeShort *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_serialize_to_cdr_buffer(
char * buffer,
unsigned int * length,
const TypeShort *sample);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_deserialize(
PRESTypePluginEndpointData endpoint_data,
TypeShort **sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_deserialize_from_cdr_buffer(
TypeShort *sample,
const char * buffer,
unsigned int length);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_skip(
PRESTypePluginEndpointData endpoint_data,
struct RTICdrStream *stream,
RTIBool skip_encapsulation,
RTIBool skip_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern unsigned int
TypeShortPlugin_get_serialized_sample_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeShortPlugin_get_serialized_sample_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeShortPlugin_get_serialized_sample_min_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeShortPlugin_get_serialized_sample_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment,
const TypeShort * sample);
/* --------------------------------------------------------------------------------------
Key Management functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginKeyKind
TypeShortPlugin_get_key_kind(void);
NDDSUSERDllExport extern unsigned int
TypeShortPlugin_get_serialized_key_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeShortPlugin_get_serialized_key_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_serialize_key(
PRESTypePluginEndpointData endpoint_data,
const TypeShort *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_deserialize_key_sample(
PRESTypePluginEndpointData endpoint_data,
TypeShort * sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_deserialize_key(
PRESTypePluginEndpointData endpoint_data,
TypeShort ** sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeShortPlugin_serialized_sample_to_key(
PRESTypePluginEndpointData endpoint_data,
TypeShort *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
/* Plugin Functions */
NDDSUSERDllExport extern struct PRESTypePlugin*
TypeShortPlugin_new(void);
NDDSUSERDllExport extern void
TypeShortPlugin_delete(struct PRESTypePlugin *);
#define TypeCharPlugin_get_sample PRESTypePluginDefaultEndpointData_getSample
#define TypeCharPlugin_get_buffer PRESTypePluginDefaultEndpointData_getBuffer
#define TypeCharPlugin_return_buffer PRESTypePluginDefaultEndpointData_returnBuffer
#define TypeCharPlugin_create_sample PRESTypePluginDefaultEndpointData_createSample
#define TypeCharPlugin_destroy_sample PRESTypePluginDefaultEndpointData_deleteSample
/* --------------------------------------------------------------------------------------
Support functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern TypeChar*
TypeCharPluginSupport_create_data_w_params(
const struct DDS_TypeAllocationParams_t * alloc_params);
NDDSUSERDllExport extern TypeChar*
TypeCharPluginSupport_create_data_ex(RTIBool allocate_pointers);
NDDSUSERDllExport extern TypeChar*
TypeCharPluginSupport_create_data(void);
NDDSUSERDllExport extern RTIBool
TypeCharPluginSupport_copy_data(
TypeChar *out,
const TypeChar *in);
NDDSUSERDllExport extern void
TypeCharPluginSupport_destroy_data_w_params(
TypeChar *sample,
const struct DDS_TypeDeallocationParams_t * dealloc_params);
NDDSUSERDllExport extern void
TypeCharPluginSupport_destroy_data_ex(
TypeChar *sample,RTIBool deallocate_pointers);
NDDSUSERDllExport extern void
TypeCharPluginSupport_destroy_data(
TypeChar *sample);
NDDSUSERDllExport extern void
TypeCharPluginSupport_print_data(
const TypeChar *sample,
const char *desc,
unsigned int indent);
/* ----------------------------------------------------------------------------
Callback functions:
* ---------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginParticipantData
TypeCharPlugin_on_participant_attached(
void *registration_data,
const struct PRESTypePluginParticipantInfo *participant_info,
RTIBool top_level_registration,
void *container_plugin_context,
RTICdrTypeCode *typeCode);
NDDSUSERDllExport extern void
TypeCharPlugin_on_participant_detached(
PRESTypePluginParticipantData participant_data);
NDDSUSERDllExport extern PRESTypePluginEndpointData
TypeCharPlugin_on_endpoint_attached(
PRESTypePluginParticipantData participant_data,
const struct PRESTypePluginEndpointInfo *endpoint_info,
RTIBool top_level_registration,
void *container_plugin_context);
NDDSUSERDllExport extern void
TypeCharPlugin_on_endpoint_detached(
PRESTypePluginEndpointData endpoint_data);
NDDSUSERDllExport extern void
TypeCharPlugin_return_sample(
PRESTypePluginEndpointData endpoint_data,
TypeChar *sample,
void *handle);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_copy_sample(
PRESTypePluginEndpointData endpoint_data,
TypeChar *out,
const TypeChar *in);
/* ----------------------------------------------------------------------------
(De)Serialize functions:
* ------------------------------------------------------------------------- */
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_serialize(
PRESTypePluginEndpointData endpoint_data,
const TypeChar *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_deserialize_sample(
PRESTypePluginEndpointData endpoint_data,
TypeChar *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_serialize_to_cdr_buffer(
char * buffer,
unsigned int * length,
const TypeChar *sample);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_deserialize(
PRESTypePluginEndpointData endpoint_data,
TypeChar **sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_deserialize_from_cdr_buffer(
TypeChar *sample,
const char * buffer,
unsigned int length);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_skip(
PRESTypePluginEndpointData endpoint_data,
struct RTICdrStream *stream,
RTIBool skip_encapsulation,
RTIBool skip_sample,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern unsigned int
TypeCharPlugin_get_serialized_sample_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeCharPlugin_get_serialized_sample_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeCharPlugin_get_serialized_sample_min_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeCharPlugin_get_serialized_sample_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment,
const TypeChar * sample);
/* --------------------------------------------------------------------------------------
Key Management functions:
* -------------------------------------------------------------------------------------- */
NDDSUSERDllExport extern PRESTypePluginKeyKind
TypeCharPlugin_get_key_kind(void);
NDDSUSERDllExport extern unsigned int
TypeCharPlugin_get_serialized_key_max_size_ex(
PRESTypePluginEndpointData endpoint_data,
RTIBool * overflow,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern unsigned int
TypeCharPlugin_get_serialized_key_max_size(
PRESTypePluginEndpointData endpoint_data,
RTIBool include_encapsulation,
RTIEncapsulationId encapsulation_id,
unsigned int current_alignment);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_serialize_key(
PRESTypePluginEndpointData endpoint_data,
const TypeChar *sample,
struct RTICdrStream *stream,
RTIBool serialize_encapsulation,
RTIEncapsulationId encapsulation_id,
RTIBool serialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_deserialize_key_sample(
PRESTypePluginEndpointData endpoint_data,
TypeChar * sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_deserialize_key(
PRESTypePluginEndpointData endpoint_data,
TypeChar ** sample,
RTIBool * drop_sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
NDDSUSERDllExport extern RTIBool
TypeCharPlugin_serialized_sample_to_key(
PRESTypePluginEndpointData endpoint_data,
TypeChar *sample,
struct RTICdrStream *stream,
RTIBool deserialize_encapsulation,
RTIBool deserialize_key,
void *endpoint_plugin_qos);
/* Plugin Functions */
NDDSUSERDllExport extern struct PRESTypePlugin*
TypeCharPlugin_new(void);
NDDSUSERDllExport extern void
TypeCharPlugin_delete(struct PRESTypePlugin *);
#if (defined(RTI_WIN32) || defined (RTI_WINCE)) && defined(NDDS_USER_DLL_EXPORT)
/* If the code is building on Windows, stop exporting symbols.
*/
#undef NDDSUSERDllExport
#define NDDSUSERDllExport
#endif
#endif /* NADSPlugin_1916641539_h */
/* NADS_publisher.cxx
A publication of data of type TypeChar
This file is derived from code automatically generated by the rtiddsgen
command:
rtiddsgen -language C++11 -example <arch> NADS.idl
Example publication of type TypeChar automatically generated by
'rtiddsgen'. To test them follow these steps:
(1) Compile this file and the example subscription.
(2) Start the subscription on the same domain used for RTI Data Distribution
Service with the command
objs/<arch>/NADS_subscriber <domain_id> <sample_count>
(3) Start the publication on the same domain used for RTI Data Distribution
Service with the command
objs/<arch>/NADS_publisher <domain_id> <sample_count>
(4) [Optional] Specify the list of discovery initial peers and
multicast receive addresses via an environment variable or a file
(in the current working directory) called NDDS_DISCOVERY_PEERS.
You can run any number of publishers and subscribers programs, and can
add and remove them dynamically from the domain.
Example:
To run the example application on domain <domain_id>:
On Unix:
objs/<arch>/NADS_publisher <domain_id>
objs/<arch>/NADS_subscriber <domain_id>
On Windows:
objs\<arch>\NADS_publisher <domain_id>
objs\<arch>\NADS_subscriber <domain_id>
*/
#include <iostream>
#include <dds/pub/ddspub.hpp>
#include <rti/util/util.hpp> // for sleep()
#include "NADS.hpp"
void publisher_main(int domain_id, int sample_count)
{
// Create a DomainParticipant with default Qos
dds::domain::DomainParticipant participant (domain_id);
// Create a Topic -- and automatically register the type
dds::topic::Topic<TypeChar> topic (participant, "Example TypeChar");
// Create a DataWriter with default Qos (Publisher created in-line)
dds::pub::DataWriter<TypeChar> writer(dds::pub::Publisher(participant), topic);
TypeChar sample;
for (int count = 0; count < sample_count || sample_count == 0; count++) {
// Modify the data to be written here
std::cout << "Writing TypeChar, count " << count << std::endl;
writer.write(sample);
rti::util::sleep(dds::core::Duration(4));
}
}
int main(int argc, char *argv[])
{
int domain_id = 0;
int sample_count = 0; // infinite loop
if (argc >= 2) {
domain_id = atoi(argv[1]);
}
if (argc >= 3) {
sample_count = atoi(argv[2]);
}
// To turn on additional logging, include <rti/config/Logger.hpp> and
// uncomment the following line:
// rti::config::Logger::instance().verbosity(rti::config::Verbosity::STATUS_ALL);
try {
publisher_main(domain_id, sample_count);
} catch (const std::exception& ex) {
// This will catch DDS exceptions
std::cerr << "Exception in publisher_main(): " << ex.what() << std::endl;
return -1;
}
// RTI Connext provides a finalize_participant_factory() method
// if you want to release memory used by the participant factory singleton.
// Uncomment the following line to release the singleton:
//
// dds::domain::DomainParticipant::finalize_participant_factory();
return 0;
}
/* NADS_subscriber.cxx
A subscription example
This file is derived from code automatically generated by the rtiddsgen
command:
rtiddsgen -language C++11 -example <arch> NADS.idl
Example subscription of type TypeChar automatically generated by
'rtiddsgen'. To test them, follow these steps:
(1) Compile this file and the example publication.
(2) Start the subscription on the same domain used for RTI Data Distribution
Service with the command
objs/<arch>/NADS_subscriber <domain_id> <sample_count>
(3) Start the publication on the same domain used for RTI Data Distribution
Service with the command
objs/<arch>/NADS_publisher <domain_id> <sample_count>
(4) [Optional] Specify the list of discovery initial peers and
multicast receive addresses via an environment variable or a file
(in the current working directory) called NDDS_DISCOVERY_PEERS.
You can run any number of publishers and subscribers programs, and can
add and remove them dynamically from the domain.
Example:
To run the example application on domain <domain_id>:
On UNIX systems:
objs/<arch>/NADS_publisher <domain_id>
objs/<arch>/NADS_subscriber <domain_id>
On Windows systems:
objs\<arch>\NADS_publisher <domain_id>
objs\<arch>\NADS_subscriber <domain_id>
*/
#include <algorithm>
#include <iostream>
#include <dds/sub/ddssub.hpp>
#include <dds/core/ddscore.hpp>
// Or simply include <dds/dds.hpp>
#include "NADS.hpp"
int subscriber_main(int domain_id, int sample_count)
{
// Create a DomainParticipant with default Qos
dds::domain::DomainParticipant participant(domain_id);
// Create a Topic -- and automatically register the type
dds::topic::Topic<TypeChar> topic(participant, "Example TypeChar");
// Create a DataReader with default Qos (Subscriber created in-line)
dds::sub::DataReader<TypeChar> reader(dds::sub::Subscriber(participant), topic);
// Create a ReadCondition for any data on this reader and associate a handler
int count = 0;
dds::sub::cond::ReadCondition read_condition(
reader,
dds::sub::status::DataState::any(),
[&reader, &count]()
{
// Take all samples
dds::sub::LoanedSamples<TypeChar> samples = reader.take();
for (auto sample : samples){
if (sample.info().valid()){
count++;
std::cout << sample.data() << std::endl;
}
}
} // The LoanedSamples destructor returns the loan
);
// Create a WaitSet and attach the ReadCondition
dds::core::cond::WaitSet waitset;
waitset += read_condition;
while (count < sample_count || sample_count == 0) {
// Dispatch will call the handlers associated to the WaitSet conditions
// when they activate
std::cout << "TypeChar subscriber sleeping for 4 sec..." << std::endl;
waitset.dispatch(dds::core::Duration(4)); // Wait up to 4s each time
}
return 1;
}
int main(int argc, char *argv[])
{
int domain_id = 0;
int sample_count = 0; // infinite loop
if (argc >= 2) {
domain_id = atoi(argv[1]);
}
if (argc >= 3) {
sample_count = atoi(argv[2]);
}
// To turn on additional logging, include <rti/config/Logger.hpp> and
// uncomment the following line:
// rti::config::Logger::instance().verbosity(rti::config::Verbosity::STATUS_ALL);
try {
subscriber_main(domain_id, sample_count);
} catch (const std::exception& ex) {
// This will catch DDS exceptions
std::cerr << "Exception in subscriber_main(): " << ex.what() << std::endl;
return -1;
}
// RTI Connext provides a finalize_participant_factory() method
// if you want to release memory used by the participant factory singleton.
// Uncomment the following line to release the singleton:
//
// dds::domain::DomainParticipant::finalize_participant_factory();
return 0;
}
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{FCE83303-FBAE-4E08-B252-A7A7EFFF60F6}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>NadsDDSLib</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)lib\</OutDir>
<TargetName>$(ProjectName)_64ds</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)lib</OutDir>
<TargetName>$(ProjectName)_32ds</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)lib</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)lib</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>RTI_WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.\;.\src;.\include;$(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>RTI_WIN32;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.\;.\src;.\include;$(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>RTI_WIN32;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.\;.\src;.\include;$(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>RTI_WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>.\;.\src;.\include;$(NDDSHOME)\include;$(NDDSHOME)\include\ndds;$(NDDSHOME)\include\ndds\hpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="apex_memmove.h" />
<ClInclude Include="include\NadsDDSLib\NadsDDSLib.h" />
<ClInclude Include="NADS.hpp" />
<ClInclude Include="NADSPlugin.hpp" />
<ClInclude Include="src\GenericSubscriber.h" />
<ClInclude Include="src\nadsddsimpl.h" />
<ClInclude Include="src\value_as_string.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="apex_memmove.cpp" />
<ClCompile Include="NADS.cxx" />
<ClCompile Include="NADSPlugin.cxx" />
<ClCompile Include="NADS_publisher.cxx" />
<ClCompile Include="NADS_subscriber.cxx" />
<ClCompile Include="src\GenericSubscriber.cpp" />
<ClCompile Include="src\nadsddsimpl.cpp" />
<ClCompile Include="src\nadsddslib.cpp" />
<ClCompile Include="src\value_as_string.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\NadsDDSLib\NadsDDSLib.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\nadsddsimpl.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="apex_memmove.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="NADS.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="NADSPlugin.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\GenericSubscriber.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\value_as_string.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\nadsddsimpl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="apex_memmove.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NADS_publisher.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NADS_subscriber.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NADSPlugin.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\nadsddslib.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NADS.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\GenericSubscriber.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\value_as_string.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
\ No newline at end of file
#include "apex_memmove.h"
#include <string.h> // memmove, memcpy
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) // Test for Intel/AMD architecture
#include <emmintrin.h> // Intel/AMD SSE intrinsics
#if defined(_MSC_VER)
#include <intrin.h> // __cpuid Visual Studio
#elif defined(__GNUC__)
#include <cpuid.h> // __get_cpuid GCC / LLVM (Clang)
#endif
#endif
// apex_memmove (tiberium, kryptonite and mithril) memcpy/memmove functions written by Trevor Herselman in 2014
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4146 ) // warning C4146: unary minus operator applied to unsigned type, result still unsigned
#pragma warning( disable : 4244 ) // warning C4244: '-=': conversion from '__int64' to 'std::size_t', possible loss of data
#endif
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) // Test for Intel/AMD architecture
void* APEXCALL apex_tiberium( void *dst, const void *src, size_t size )
{ // based on memmove09 for "size <= 112" and memmove40 for "size > 112"
if ( size <= 112 )
{
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size >= 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
if ( size > 32 )
{
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
if ( size > 48 )
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + 32) );
if ( size > 64 )
{
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + 48) );
if ( size > 80 )
{
const __m128i xmm4 = _mm_loadu_si128( (__m128i*)((char*)src + 64) );
if ( size > 96 )
{
const __m128i xmm5 = _mm_loadu_si128( (__m128i*)((char*)src + 80) );
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
_mm_storeu_si128( (__m128i*)((char*)dst + 64), xmm4 );
_mm_storeu_si128( (__m128i*)((char*)dst + 80), xmm5 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
_mm_storeu_si128( (__m128i*)((char*)dst + 64), xmm4 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
return dst;
}
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
return dst;
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return dst;
}
else
{
void * const ret = dst;
if ( ((size_t)dst - (size_t)src) >= size )
{
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
size -= offset; // "Remaining data after loop"
offset = -offset; // "Negative index from the end"
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_storeu_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
if ( size > 48 )
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + 32) );
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
else // do forward streaming copy/move
{
// We MUST do prealignment on streaming copies!
const size_t prealign = -(size_t)dst & 0xf;
if ( prealign )
{
if ( prealign >= 8 )
{
long long rax = *(long long*)src;
if ( prealign > 8 )
{
long long rcx = *(long long*)((char*)src + prealign - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + prealign - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( prealign >= 4 )
{
int eax = *(int*)src;
if ( prealign > 4 )
{
int ecx = *(int*)((char*)src + prealign - 4);
*(int*)dst = eax;
*(int*)((char*)dst + prealign - 4) = ecx;
}
else *(int*)dst = eax;
}
else
{
char al = *(char*)src;
if ( prealign > 1 )
{
short cx = *(short*)((char*)src + prealign - 2);
*(char*)dst = al;
*(short*)((char*)dst + prealign - 2) = cx;
}
else *(char*)dst = al;
}
src = (char*)src + prealign;
dst = (char*)dst + prealign;
size -= prealign;
}
// Begin prefetching upto 4KB
for ( long long offset = 0; offset < 4096; offset += 256 )
{
_mm_prefetch( ((char*)src + offset), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 192), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
offset = -offset; // "Negative index from the end"
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset + 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
offset = -4096;
dst = (char*)dst + 4096;
src = (char*)src + 4096;
_mm_prefetch( ((char*)src + size - 64), _MM_HINT_NTA ); // prefetch the final tail section
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size - 32) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 32), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return ret;
}
else // src < dst ... do reverse copy
{
src = (char*)src + size;
dst = (char*)dst + size;
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
size -= offset; // "Remaining data after loop"
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 64;
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
size = -size;
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
if ( size > 48 )
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src - 48) );
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst - 48), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
else // do reversed streaming copy/move
{
// We MUST do prealignment on streaming copies!
const size_t prealign = (size_t)dst & 0xf;
if ( prealign )
{
src = (char*)src - prealign;
dst = (char*)dst - prealign;
size -= prealign;
if ( prealign >= 8 )
{
long long rax = *(long long*)((char*)src + prealign - 8);
if ( prealign > 8 )
{
long long rcx = *(long long*)src;
*(long long*)((char*)dst + prealign - 8) = rax;
*(long long*)dst = rcx;
}
else *(long long*)dst = rax; // different on purpose, because we know the exact size now, which is 8, and "dst" has already been aligned!
}
else if ( prealign >= 4 )
{
int eax = *(int*)((char*)src + prealign - 4);
if ( prealign > 4 )
{
int ecx = *(int*)src;
*(int*)((char*)dst + prealign - 4) = eax;
*(int*)dst = ecx;
}
else *(int*)dst = eax; // different on purpose!
}
else
{
char al = *(char*)((char*)src + prealign - 1);
if ( prealign > 1 )
{
short cx = *(short*)src;
*(char*)((char*)dst + prealign - 1) = al;
*(short*)dst = cx;
}
else *(char*)dst = al; // different on purpose!
}
}
// Begin prefetching upto 4KB
for ( long long offset = 0; offset > -4096; offset -= 256 )
{
_mm_prefetch( ((char*)src + offset - 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 192), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 256), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 64;
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset - 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
offset = 4096;
dst = (char*)dst - 4096;
src = (char*)src - 4096;
_mm_prefetch( ((char*)src - 64), _MM_HINT_NTA ); // prefetch the final tail section
offset -= 64;
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
if ( size > 32 )
{
size = -size;
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size + 16) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size + 16), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
size = -size;
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)((char*)src - 8);
if ( size > 8 )
{
size = -size; // that's right, we're converting an unsigned value to a negative, saves 2 clock cycles!
long long rcx = *(long long*)((char*)src + size);
*(long long*)((char*)dst - 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
else *(long long*)((char*)dst - 8) = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)((char*)src - 4);
if ( size > 4 )
{
size = -size;
int ecx = *(int*)((char*)src + size);
*(int*)((char*)dst - 4) = eax;
*(int*)((char*)dst + size) = ecx;
}
else *(int*)((char*)dst - 4) = eax;
}
else if ( size >= 1 )
{
char al = *((char*)src - 1);
if ( size > 1 )
{
size = -size;
short cx = *(short*)((char*)src + size);
*((char*)dst - 1) = al;
*(short*)((char*)dst + size) = cx;
}
else *((char*)dst - 1) = al;
}
return ret;
}
}
}
void* APEXCALL apex_kryptonite( void *dst, const void *src, size_t size )
{ // based on memmove09 for "size <= 112" and memmove41 for "size > 112"; memmove09's "size <= 112" proved fastest overall (weighted), even on Core i5!
if ( size <= 112 )
{
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size >= 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
if ( size > 32 )
{
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
if ( size > 48 )
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + 32) );
if ( size > 64 )
{
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + 48) );
if ( size > 80 )
{
const __m128i xmm4 = _mm_loadu_si128( (__m128i*)((char*)src + 64) );
if ( size > 96 )
{
const __m128i xmm5 = _mm_loadu_si128( (__m128i*)((char*)src + 80) );
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
_mm_storeu_si128( (__m128i*)((char*)dst + 64), xmm4 );
_mm_storeu_si128( (__m128i*)((char*)dst + 80), xmm5 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
_mm_storeu_si128( (__m128i*)((char*)dst + 64), xmm4 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
return dst;
}
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
return dst;
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return dst;
}
else
{
void * const ret = dst;
if ( ((size_t)dst - (size_t)src) >= size )
{
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x20); // "Round down to nearest multiple of 64"
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
size -= offset; // "Remaining data after loop"
offset = -offset; // "Negative index from the end"
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
_mm_storeu_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
} while ( offset += 32 );
if ( size >= 16 )
{
if ( size > 16 )
{
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
_mm_storeu_si128( (__m128i*)dst, xmm0 );
return ret;
}
_mm_storeu_si128( (__m128i*)dst, _mm_loadu_si128( (__m128i*)src ) );
return ret;
}
}
else // do forward streaming copy/move
{
// We MUST do prealignment on streaming copies!
const size_t prealign = -(size_t)dst & 0xf;
if ( prealign )
{
if ( prealign >= 8 )
{
long long rax = *(long long*)src;
if ( prealign > 8 )
{
long long rcx = *(long long*)((char*)src + prealign - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + prealign - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( prealign >= 4 )
{
int eax = *(int*)src;
if ( prealign > 4 )
{
int ecx = *(int*)((char*)src + prealign - 4);
*(int*)dst = eax;
*(int*)((char*)dst + prealign - 4) = ecx;
}
else *(int*)dst = eax;
}
else
{
char al = *(char*)src;
if ( prealign > 1 )
{
short cx = *(short*)((char*)src + prealign - 2);
*(char*)dst = al;
*(short*)((char*)dst + prealign - 2) = cx;
}
else *(char*)dst = al;
}
src = (char*)src + prealign;
dst = (char*)dst + prealign;
size -= prealign;
}
// Begin prefetching upto 4KB
for ( long long offset = 0; offset < 4096; offset += 256 )
{
_mm_prefetch( ((char*)src + offset), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 192), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
offset = -offset; // "Negative index from the end"
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset + 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
offset = -4096;
dst = (char*)dst + 4096;
src = (char*)src + 4096;
_mm_prefetch( ((char*)src + size - 64), _MM_HINT_NTA ); // prefetch the final tail section
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size - 32) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 32), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return ret;
}
else // src < dst ... do reverse copy
{
src = (char*)src + size;
dst = (char*)dst + size;
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x20); // "Round down to nearest multiple of 64"
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
size -= offset; // "Remaining data after loop"
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 32;
do
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 32) >= 0 );
if ( size >= 16 )
{
if ( size > 16 )
{
size = -size;
// The order has been mixed so the compiler will not re-order the statements!
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
_mm_storeu_si128( (__m128i*)((char*)dst - 16), _mm_loadu_si128( (__m128i*)((char*)src - 16) ) );
return ret;
}
}
else // do reversed streaming copy/move
{
// We MUST do prealignment on streaming copies!
const size_t prealign = (size_t)dst & 0xf;
if ( prealign )
{
src = (char*)src - prealign;
dst = (char*)dst - prealign;
size -= prealign;
if ( prealign >= 8 )
{
long long rax = *(long long*)((char*)src + prealign - 8);
if ( prealign > 8 )
{
long long rcx = *(long long*)src;
*(long long*)((char*)dst + prealign - 8) = rax;
*(long long*)dst = rcx;
}
else *(long long*)dst = rax; // different on purpose, because we know the exact size now, which is 8, and "dst" has already been aligned!
}
else if ( prealign >= 4 )
{
int eax = *(int*)((char*)src + prealign - 4);
if ( prealign > 4 )
{
int ecx = *(int*)src;
*(int*)((char*)dst + prealign - 4) = eax;
*(int*)dst = ecx;
}
else *(int*)dst = eax; // different on purpose!
}
else
{
char al = *(char*)((char*)src + prealign - 1);
if ( prealign > 1 )
{
short cx = *(short*)src;
*(char*)((char*)dst + prealign - 1) = al;
*(short*)dst = cx;
}
else *(char*)dst = al; // different on purpose!
}
}
// Begin prefetching upto 4KB
for ( long long offset = 0; offset > -4096; offset -= 256 )
{
_mm_prefetch( ((char*)src + offset - 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 192), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 256), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 64;
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset - 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
offset = 4096;
dst = (char*)dst - 4096;
src = (char*)src - 4096;
_mm_prefetch( ((char*)src - 64), _MM_HINT_NTA ); // prefetch the final tail section
offset -= 64;
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
if ( size > 32 )
{
size = -size;
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size + 16) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size + 16), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
size = -size;
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)((char*)src - 8);
if ( size > 8 )
{
size = -size; // that's right, we're converting an unsigned value to a negative, saves 2 clock cycles!
long long rcx = *(long long*)((char*)src + size);
*(long long*)((char*)dst - 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
else *(long long*)((char*)dst - 8) = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)((char*)src - 4);
if ( size > 4 )
{
size = -size;
int ecx = *(int*)((char*)src + size);
*(int*)((char*)dst - 4) = eax;
*(int*)((char*)dst + size) = ecx;
}
else *(int*)((char*)dst - 4) = eax;
}
else if ( size >= 1 )
{
char al = *((char*)src - 1);
if ( size > 1 )
{
size = -size;
short cx = *(short*)((char*)src + size);
*((char*)dst - 1) = al;
*(short*)((char*)dst + size) = cx;
}
else *((char*)dst - 1) = al;
}
return ret;
}
}
}
#if (!defined(_M_X64) && !defined(__x86_64__)) // `mithril` is only used in 32-bit code (not necessary for 64-bit)
// "Mithril" - Written by Trevor Herselman on 4 December 2013 @ 9pm
// This is my "compact power house"! Decided to make a "mini" powerful version, one that can easily beat Microsoft's memmove, but doesn't contain all the "bells and whistles"!
// Probably Very similar to mm04 in terms of performance, but this should be faster under all conditions and ranges!
// Includes a new "prealignment" check that detects if "size <= 48", then uses 3x SSE loads instead of passing through the prealignment code!
// originally called memmove13() during development (mm13 is based on mm04)
void* APEXCALL apex_mithril( void *dst, const void *src, size_t size )
{
if ( size <= 32 )
{
if ( size >= 16 )
{
long long r1 = *(long long*)src;
long long r2 = *(long long*)((char*)src + 8);
if ( size > 16 )
{
long long r3 = *(long long*)((char*)src + size - 16);
long long r4 = *(long long*)((char*)src + size - 8);
*(long long*)dst = r1;
*(long long*)((char*)dst + 8) = r2;
*(long long*)((char*)dst + size - 16) = r3;
*(long long*)((char*)dst + size - 8) = r4;
return dst;
}
*(long long*)dst = r1;
*(long long*)((char*)dst + 8) = r2;
return dst;
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return dst;
}
else
{
void * const ret = dst;
if ( ((size_t)dst - (size_t)src) >= size )
{
if ( (size_t)dst & 0xf )
{
const size_t prealign = -(size_t)dst & 0xf;
if ( size <= 48 )
{
// prealignment might drop the remaining size below 32-bytes,
// we could also check "size - prealign <= 32", but since we're already here,
// and these statements can load upto 48-bytes, we might as well just do it!
// We `could` copy up to 64-bytes without any additional checks by using another SSE "loadu" & "storeu"
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
long long r1 = *(long long*)((char*)src + 16);
long long r2 = *(long long*)((char*)src + 24);
long long r3 = *(long long*)((char*)src + size - 16);
long long r4 = *(long long*)((char*)src + size - 8);
_mm_storeu_si128( (__m128i*)dst, xmm0 );
*(long long*)((char*)dst + 16) = r1;
*(long long*)((char*)dst + 24) = r2;
*(long long*)((char*)dst + size - 16) = r3;
*(long long*)((char*)dst + size - 8) = r4;
return dst;
}
if ( prealign >= 8 )
{
long long rax = *(long long*)src;
if ( prealign > 8 )
{
long long rcx = *(long long*)((char*)src + prealign - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + prealign - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( prealign >= 4 )
{
int eax = *(int*)src;
if ( prealign > 4 )
{
int ecx = *(int*)((char*)src + prealign - 4);
*(int*)dst = eax;
*(int*)((char*)dst + prealign - 4) = ecx;
}
else *(int*)dst = eax;
}
else
{
char al = *(char*)src;
if ( prealign > 1 )
{
short cx = *(short*)((char*)src + prealign - 2);
*(char*)dst = al;
*(short*)((char*)dst + prealign - 2) = cx;
}
else *(char*)dst = al;
}
src = (char*)src + prealign;
dst = (char*)dst + prealign;
size -= prealign;
}
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x20); // "Round down to nearest multiple of 32"
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
size -= offset; // "Remaining data after loop"
offset = -offset; // "Negative index from the end"
if ( ((size_t)src & 0xf) == 0 )
{
do
{
const __m128i xmm0 = _mm_load_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_load_si128( (__m128i*)((char*)src + offset + 16) );
_mm_store_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_store_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
} while ( offset += 32 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_load_si128( (__m128i*)src );
if ( size > 16 )
{
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_store_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
else
{
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
_mm_store_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_store_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
} while ( offset += 32 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_store_si128( (__m128i*)dst, xmm0 );
return (void*)ret;
}
}
}
else // do forward streaming copy/move
{
// Begin prefetching upto 4KB
for ( long long i = 0; i < 4096; i += 256 )
{
_mm_prefetch( ((char*)src + i), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + i + 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + i + 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + i + 192), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
offset = -offset; // "Negative index from the end"
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset + 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
offset = -4096;
dst = (char*)dst + 4096;
src = (char*)src + 4096;
_mm_prefetch( ((char*)src + size - 64), _MM_HINT_NTA ); // prefetch the final tail section
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size - 32) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 32), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return ret;
}
else // src < dst ... do reverse copy
{
src = (char*)src + size;
dst = (char*)dst + size;
const size_t prealign = (size_t)dst & 0xf;
if ( prealign )
{
if ( size <= 48 )
{
// prealignment might drop the remaining size below 32-bytes,
// we could also check "size - prealign <= 32", but since we're already here,
// and these statements can load upto 48-bytes, we might as well just do it!
// Actually, we can copy upto 64-bytes without any additional checks!
size = -size;
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) ); // first 32-bytes in reverse
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 ); // the "back" bytes are actually the base address!
return dst;
}
src = (char*)src - prealign;
dst = (char*)dst - prealign;
size -= prealign;
if ( prealign >= 8 )
{
long long rax = *(long long*)((char*)src + prealign - 8);
if ( prealign > 8 )
{
long long rcx = *(long long*)src;
*(long long*)((char*)dst + prealign - 8) = rax;
*(long long*)dst = rcx;
}
else *(long long*)dst = rax; // different on purpose, because we know the exact size now!
}
else if ( prealign >= 4 )
{
int eax = *(int*)((char*)src + prealign - 4);
if ( prealign > 4 )
{
int ecx = *(int*)src;
*(int*)((char*)dst + prealign - 4) = eax;
*(int*)dst = ecx;
}
else *(int*)dst = eax; // different on purpose!
}
else
{
char al = *(char*)((char*)src + prealign - 1);
if ( prealign > 1 )
{
short cx = *(short*)src;
*(char*)((char*)dst + prealign - 1) = al;
*(short*)dst = cx;
}
else *(char*)dst = al; // different on purpose!
}
}
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x20); // "Round down to nearest multiple of 32"
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
size -= offset; // "Remaining data after loop"
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 32; // MSVC completely re-engineers this!
if ( ((size_t)src & 0xf) == 0 )
{
do
{
const __m128i xmm0 = _mm_load_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm1 = _mm_load_si128( (__m128i*)((char*)src + offset) );
_mm_store_si128( (__m128i*)((char*)dst + offset + 16), xmm0 );
_mm_store_si128( (__m128i*)((char*)dst + offset), xmm1 );
} while ( (offset -= 32) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_load_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
size = -size;
//const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) ); // SSE2 alternative
long long rax = *(long long*)((char*)src + size + 8);
long long rcx = *(long long*)((char*)src + size);
//_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
*(long long*)((char*)dst + size + 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
_mm_store_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
else
{
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_store_si128( (__m128i*)((char*)dst + offset + 16), xmm0 );
_mm_store_si128( (__m128i*)((char*)dst + offset), xmm1 );
} while ( (offset -= 32) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
size = -size;
long long rax = *(long long*)((char*)src + size + 8);
long long rcx = *(long long*)((char*)src + size);
*(long long*)((char*)dst + size + 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
_mm_store_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
}
else // do reversed streaming copy/move
{
// Begin prefetching upto 4KB
for ( long long offset = 0; offset > -4096; offset -= 256 )
{
_mm_prefetch( ((char*)src + offset - 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 192), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 256), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 32"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 64;
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset - 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
offset = 4096;
dst = (char*)dst - 4096;
src = (char*)src - 4096;
_mm_prefetch( ((char*)src - 64), _MM_HINT_NTA ); // prefetch the final tail section
offset -= 64;
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
if ( size > 32 )
{
size = -size;
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size + 16) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size + 16), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
size = -size;
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)((char*)src - 8);
if ( size > 8 )
{
size = -size; // that's right, we're converting an unsigned value to a negative, saves 2 clock cycles!
long long rcx = *(long long*)((char*)src + size);
*(long long*)((char*)dst - 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
else *(long long*)((char*)dst - 8) = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)((char*)src - 4);
if ( size > 4 )
{
size = -size;
int ecx = *(int*)((char*)src + size);
*(int*)((char*)dst - 4) = eax;
*(int*)((char*)dst + size) = ecx;
}
else *(int*)((char*)dst - 4) = eax;
}
else if ( size >= 1 )
{
char al = *((char*)src - 1);
if ( size > 1 )
{
size = -size;
short cx = *(short*)((char*)src + size);
*((char*)dst - 1) = al;
*(short*)((char*)dst + size) = cx;
}
else *((char*)dst - 1) = al;
}
return ret;
}
}
}
#endif // end test for 32-bit
#endif // end test for Intel/AMD (32-bit & 64-bit)
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
void* APEXCALL apex_memmove_dispatcher( void *dst, const void *src, size_t size )
{
#if (defined(_M_X64) || defined(__x86_64__) || defined(__i386) || defined(_M_IX86)) && (defined(_MSC_VER) || defined(__GNUC__)) // Compiler and architecture test (Intel/AMD Architecture)! Visual Studio and GCC / LLVM (Clang)
#if defined(_MSC_VER)
int cpuid[4] = {-1}; // Visual Studio
__cpuid( cpuid, 1 );
#define bit_SSE2 (1 << 26) // Taken from GCC <cpuid.h> ... just more visual & descriptive!
#define bit_SSSE3 (1 << 9)
#define bit_SSE4_2 (1 << 20)
#else
unsigned int cpuid[4]; // GCC / LLVM (Clang)
__get_cpuid(1, &cpuid[0], &cpuid[1], &cpuid[2], &cpuid[3]);
#endif
#if defined(_M_X64) || defined(__x86_64__) // 64-bit
if ( cpuid[2] & bit_SSE4_2 ) // detect SSE4.2, available on Core i and newer processors, they include "fast unaligned" memory access
apex_memcpy = apex_memmove = &apex_kryptonite;
else
apex_memcpy = apex_memmove = &apex_tiberium;
#else // 32-bit
if ( cpuid[2] & bit_SSE4_2 ) // detect SSE4.2, available on Core i and newer processors, they include "fast unaligned" memory access
apex_memcpy = apex_memmove = &apex_kryptonite;
else if ( cpuid[2] & bit_SSSE3 ) // detect SSSE3, available on Core/Core 2 and newer
apex_memcpy = apex_memmove = &apex_tiberium; // `tiberium` CAN run with the SSE2 instructions alone, however there was something about very old SSE2 (only) computers, some penalty when using `tiberiums` algorithm, so I've restricted `tiberium` to Core/Core 2 based machines on 32-bit by doing this!
else if ( cpuid[3] & bit_SSE2 )
apex_memcpy = apex_memmove = &apex_mithril; // this is for very, very old computers with SSE2 only! eg. old Pentium 4! There was something about computers WITHOUT SSSE3 (Core microarchitecture) that made `tiberium` a bit slower. So this is for super old (P4) PC's!
else {
apex_memcpy = &memcpy; // No SSE2 no cry!
apex_memmove = &memmove;
}
#endif
#else // unknown compiler or architecture! eg. __arm__ / __mips__ / __ppc__ / __sparc / __ia64 (Itanium) etc.
#if defined(__x86_64__)
apex_memcpy = apex_memmove = &apex_tiberium; // unknown compiler BUT it declared support for Intel/AMD x64/AMD64 (64-bit), so it should come with the <emmintrin.h> file from Intel! 64-bit x64/AMD64 includes SSE2! This includes `Portland (PGCC/PGCPP)`, `Oracle Solaris Studio` and `Intel compiler (ICC)`! I don't have code for CPUID for these compilers so I don't know how to check for SSE2/SSSE3/SSE4.2 on them!
#else
apex_memcpy = &memcpy; // unknown compiler or architecture!
apex_memmove = &memmove;
#endif
#endif
return apex_memmove( dst, src, size ); // safe to call memmove even for memcpy!
}
void *(APEXCALL *apex_memcpy)( void *dst, const void *src, size_t size ) = apex_memmove_dispatcher;
void *(APEXCALL *apex_memmove)( void *dst, const void *src, size_t size ) = apex_memmove_dispatcher;
#include "stdafx.h"
#include "apex_memmove.h"
#include <cstring> // std::memmove, std::memcpy
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) // Test for Intel/AMD architecture
#include <emmintrin.h> // Intel/AMD SSE intrinsics
#if defined(_MSC_VER)
#include <intrin.h> // __cpuid Visual Studio
#elif defined(__GNUC__)
#include <cpuid.h> // __get_cpuid GCC / LLVM (Clang)
#endif
#endif
namespace apex
{
// apex memmove (tiberium, kryptonite and mithril) memcpy/memmove functions written by Trevor Herselman in 2014
#if defined(_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4146 ) // warning C4146: unary minus operator applied to unsigned type, result still unsigned
#pragma warning( disable : 4244 ) // warning C4244: '-=': conversion from '__int64' to 'std::size_t', possible loss of data
#endif
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86) // Test for Intel/AMD architecture
void* APEXCALL tiberium( void *dst, const void *src, size_t size )
{ // based on memmove09 for "size <= 112" and memmove40 for "size > 112"
if ( size <= 112 )
{
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size >= 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
if ( size > 32 )
{
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
if ( size > 48 )
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + 32) );
if ( size > 64 )
{
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + 48) );
if ( size > 80 )
{
const __m128i xmm4 = _mm_loadu_si128( (__m128i*)((char*)src + 64) );
if ( size > 96 )
{
const __m128i xmm5 = _mm_loadu_si128( (__m128i*)((char*)src + 80) );
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
_mm_storeu_si128( (__m128i*)((char*)dst + 64), xmm4 );
_mm_storeu_si128( (__m128i*)((char*)dst + 80), xmm5 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
_mm_storeu_si128( (__m128i*)((char*)dst + 64), xmm4 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
return dst;
}
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
return dst;
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return dst;
}
else
{
void * const ret = dst;
if ( ((size_t)dst - (size_t)src) >= size )
{
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
size -= offset; // "Remaining data after loop"
offset = -offset; // "Negative index from the end"
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_storeu_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
if ( size > 48 )
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + 32) );
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
else // do forward streaming copy/move
{
// We MUST do prealignment on streaming copies!
const size_t prealign = -(size_t)dst & 0xf;
if ( prealign )
{
if ( prealign >= 8 )
{
long long rax = *(long long*)src;
if ( prealign > 8 )
{
long long rcx = *(long long*)((char*)src + prealign - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + prealign - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( prealign >= 4 )
{
int eax = *(int*)src;
if ( prealign > 4 )
{
int ecx = *(int*)((char*)src + prealign - 4);
*(int*)dst = eax;
*(int*)((char*)dst + prealign - 4) = ecx;
}
else *(int*)dst = eax;
}
else
{
char al = *(char*)src;
if ( prealign > 1 )
{
short cx = *(short*)((char*)src + prealign - 2);
*(char*)dst = al;
*(short*)((char*)dst + prealign - 2) = cx;
}
else *(char*)dst = al;
}
src = (char*)src + prealign;
dst = (char*)dst + prealign;
size -= prealign;
}
// Begin prefetching upto 4KB
for ( long long offset = 0; offset < 4096; offset += 256 )
{
_mm_prefetch( ((char*)src + offset), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 192), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
offset = -offset; // "Negative index from the end"
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset + 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
offset = -4096;
dst = (char*)dst + 4096;
src = (char*)src + 4096;
_mm_prefetch( ((char*)src + size - 64), _MM_HINT_NTA ); // prefetch the final tail section
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size - 32) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 32), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return ret;
}
else // src < dst ... do reverse copy
{
src = (char*)src + size;
dst = (char*)dst + size;
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
size -= offset; // "Remaining data after loop"
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 64;
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
size = -size;
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
if ( size > 48 )
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src - 48) );
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst - 48), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm3 );
return ret;
}
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
else // do reversed streaming copy/move
{
// We MUST do prealignment on streaming copies!
const size_t prealign = (size_t)dst & 0xf;
if ( prealign )
{
src = (char*)src - prealign;
dst = (char*)dst - prealign;
size -= prealign;
if ( prealign >= 8 )
{
long long rax = *(long long*)((char*)src + prealign - 8);
if ( prealign > 8 )
{
long long rcx = *(long long*)src;
*(long long*)((char*)dst + prealign - 8) = rax;
*(long long*)dst = rcx;
}
else *(long long*)dst = rax; // different on purpose, because we know the exact size now, which is 8, and "dst" has already been aligned!
}
else if ( prealign >= 4 )
{
int eax = *(int*)((char*)src + prealign - 4);
if ( prealign > 4 )
{
int ecx = *(int*)src;
*(int*)((char*)dst + prealign - 4) = eax;
*(int*)dst = ecx;
}
else *(int*)dst = eax; // different on purpose!
}
else
{
char al = *(char*)((char*)src + prealign - 1);
if ( prealign > 1 )
{
short cx = *(short*)src;
*(char*)((char*)dst + prealign - 1) = al;
*(short*)dst = cx;
}
else *(char*)dst = al; // different on purpose!
}
}
// Begin prefetching upto 4KB
for ( long long offset = 0; offset > -4096; offset -= 256 )
{
_mm_prefetch( ((char*)src + offset - 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 192), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 256), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 64;
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset - 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
offset = 4096;
dst = (char*)dst - 4096;
src = (char*)src - 4096;
_mm_prefetch( ((char*)src - 64), _MM_HINT_NTA ); // prefetch the final tail section
offset -= 64;
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
if ( size > 32 )
{
size = -size;
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size + 16) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size + 16), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
size = -size;
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)((char*)src - 8);
if ( size > 8 )
{
size = -size; // that's right, we're converting an unsigned value to a negative, saves 2 clock cycles!
long long rcx = *(long long*)((char*)src + size);
*(long long*)((char*)dst - 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
else *(long long*)((char*)dst - 8) = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)((char*)src - 4);
if ( size > 4 )
{
size = -size;
int ecx = *(int*)((char*)src + size);
*(int*)((char*)dst - 4) = eax;
*(int*)((char*)dst + size) = ecx;
}
else *(int*)((char*)dst - 4) = eax;
}
else if ( size >= 1 )
{
char al = *((char*)src - 1);
if ( size > 1 )
{
size = -size;
short cx = *(short*)((char*)src + size);
*((char*)dst - 1) = al;
*(short*)((char*)dst + size) = cx;
}
else *((char*)dst - 1) = al;
}
return ret;
}
}
}
void* APEXCALL kryptonite( void *dst, const void *src, size_t size )
{ // based on memmove09 for "size <= 112" and memmove41 for "size > 112"; memmove09's "size <= 112" proved fastest overall (weighted), even on Core i5!
if ( size <= 112 )
{
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size >= 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
if ( size > 32 )
{
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
if ( size > 48 )
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + 32) );
if ( size > 64 )
{
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + 48) );
if ( size > 80 )
{
const __m128i xmm4 = _mm_loadu_si128( (__m128i*)((char*)src + 64) );
if ( size > 96 )
{
const __m128i xmm5 = _mm_loadu_si128( (__m128i*)((char*)src + 80) );
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
_mm_storeu_si128( (__m128i*)((char*)dst + 64), xmm4 );
_mm_storeu_si128( (__m128i*)((char*)dst + 80), xmm5 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
_mm_storeu_si128( (__m128i*)((char*)dst + 64), xmm4 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + 48), xmm3 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + 32), xmm2 );
return dst;
}
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + 16), xmm1 );
return dst;
}
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_storeu_si128( (__m128i*)dst, xmm0 );
return dst;
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return dst;
}
else
{
void * const ret = dst;
if ( ((size_t)dst - (size_t)src) >= size )
{
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x20); // "Round down to nearest multiple of 64"
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
size -= offset; // "Remaining data after loop"
offset = -offset; // "Negative index from the end"
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
_mm_storeu_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
} while ( offset += 32 );
if ( size >= 16 )
{
if ( size > 16 )
{
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
_mm_storeu_si128( (__m128i*)dst, xmm0 );
return ret;
}
_mm_storeu_si128( (__m128i*)dst, _mm_loadu_si128( (__m128i*)src ) );
return ret;
}
}
else // do forward streaming copy/move
{
// We MUST do prealignment on streaming copies!
const size_t prealign = -(size_t)dst & 0xf;
if ( prealign )
{
if ( prealign >= 8 )
{
long long rax = *(long long*)src;
if ( prealign > 8 )
{
long long rcx = *(long long*)((char*)src + prealign - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + prealign - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( prealign >= 4 )
{
int eax = *(int*)src;
if ( prealign > 4 )
{
int ecx = *(int*)((char*)src + prealign - 4);
*(int*)dst = eax;
*(int*)((char*)dst + prealign - 4) = ecx;
}
else *(int*)dst = eax;
}
else
{
char al = *(char*)src;
if ( prealign > 1 )
{
short cx = *(short*)((char*)src + prealign - 2);
*(char*)dst = al;
*(short*)((char*)dst + prealign - 2) = cx;
}
else *(char*)dst = al;
}
src = (char*)src + prealign;
dst = (char*)dst + prealign;
size -= prealign;
}
// Begin prefetching upto 4KB
for ( long long offset = 0; offset < 4096; offset += 256 )
{
_mm_prefetch( ((char*)src + offset), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset + 192), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
offset = -offset; // "Negative index from the end"
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset + 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
offset = -4096;
dst = (char*)dst + 4096;
src = (char*)src + 4096;
_mm_prefetch( ((char*)src + size - 64), _MM_HINT_NTA ); // prefetch the final tail section
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size - 32) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 32), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return ret;
}
else // src < dst ... do reverse copy
{
src = (char*)src + size;
dst = (char*)dst + size;
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x20); // "Round down to nearest multiple of 64"
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
size -= offset; // "Remaining data after loop"
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 32;
do
{
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_storeu_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_storeu_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 32) >= 0 );
if ( size >= 16 )
{
if ( size > 16 )
{
size = -size;
// The order has been mixed so the compiler will not re-order the statements!
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
_mm_storeu_si128( (__m128i*)((char*)dst - 16), _mm_loadu_si128( (__m128i*)((char*)src - 16) ) );
return ret;
}
}
else // do reversed streaming copy/move
{
// We MUST do prealignment on streaming copies!
const size_t prealign = (size_t)dst & 0xf;
if ( prealign )
{
src = (char*)src - prealign;
dst = (char*)dst - prealign;
size -= prealign;
if ( prealign >= 8 )
{
long long rax = *(long long*)((char*)src + prealign - 8);
if ( prealign > 8 )
{
long long rcx = *(long long*)src;
*(long long*)((char*)dst + prealign - 8) = rax;
*(long long*)dst = rcx;
}
else *(long long*)dst = rax; // different on purpose, because we know the exact size now, which is 8, and "dst" has already been aligned!
}
else if ( prealign >= 4 )
{
int eax = *(int*)((char*)src + prealign - 4);
if ( prealign > 4 )
{
int ecx = *(int*)src;
*(int*)((char*)dst + prealign - 4) = eax;
*(int*)dst = ecx;
}
else *(int*)dst = eax; // different on purpose!
}
else
{
char al = *(char*)((char*)src + prealign - 1);
if ( prealign > 1 )
{
short cx = *(short*)src;
*(char*)((char*)dst + prealign - 1) = al;
*(short*)dst = cx;
}
else *(char*)dst = al; // different on purpose!
}
}
// Begin prefetching upto 4KB
for ( long long offset = 0; offset > -4096; offset -= 256 )
{
_mm_prefetch( ((char*)src + offset - 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 192), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 256), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 64;
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset - 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
offset = 4096;
dst = (char*)dst - 4096;
src = (char*)src - 4096;
_mm_prefetch( ((char*)src - 64), _MM_HINT_NTA ); // prefetch the final tail section
offset -= 64;
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
if ( size > 32 )
{
size = -size;
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size + 16) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size + 16), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
size = -size;
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)((char*)src - 8);
if ( size > 8 )
{
size = -size; // that's right, we're converting an unsigned value to a negative, saves 2 clock cycles!
long long rcx = *(long long*)((char*)src + size);
*(long long*)((char*)dst - 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
else *(long long*)((char*)dst - 8) = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)((char*)src - 4);
if ( size > 4 )
{
size = -size;
int ecx = *(int*)((char*)src + size);
*(int*)((char*)dst - 4) = eax;
*(int*)((char*)dst + size) = ecx;
}
else *(int*)((char*)dst - 4) = eax;
}
else if ( size >= 1 )
{
char al = *((char*)src - 1);
if ( size > 1 )
{
size = -size;
short cx = *(short*)((char*)src + size);
*((char*)dst - 1) = al;
*(short*)((char*)dst + size) = cx;
}
else *((char*)dst - 1) = al;
}
return ret;
}
}
}
#if (!defined(_M_X64) && !defined(__x86_64__)) // `mithril` is only used in 32-bit code (not necessary for 64-bit)
// "Mithril" - Written by Trevor Herselman on 4 December 2013 @ 9pm
// This is my "compact power house"! Decided to make a "mini" powerful version, one that can easily beat Microsoft's memmove, but doesn't contain all the "bells and whistles"!
// Probably Very similar to mm04 in terms of performance, but this should be faster under all conditions and ranges!
// Includes a new "prealignment" check that detects if "size <= 48", then uses 3x SSE loads instead of passing through the prealignment code!
// originally called memmove13() during development (mm13 is based on mm04)
void* APEXCALL mithril( void *dst, const void *src, size_t size )
{
if ( size <= 32 )
{
if ( size >= 16 )
{
long long r1 = *(long long*)src;
long long r2 = *(long long*)((char*)src + 8);
if ( size > 16 )
{
long long r3 = *(long long*)((char*)src + size - 16);
long long r4 = *(long long*)((char*)src + size - 8);
*(long long*)dst = r1;
*(long long*)((char*)dst + 8) = r2;
*(long long*)((char*)dst + size - 16) = r3;
*(long long*)((char*)dst + size - 8) = r4;
return dst;
}
*(long long*)dst = r1;
*(long long*)((char*)dst + 8) = r2;
return dst;
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return dst;
}
else
{
void * const ret = dst;
if ( ((size_t)dst - (size_t)src) >= size )
{
if ( (size_t)dst & 0xf )
{
const size_t prealign = -(size_t)dst & 0xf;
if ( size <= 48 )
{
// prealignment might drop the remaining size below 32-bytes,
// we could also check "size - prealign <= 32", but since we're already here,
// and these statements can load upto 48-bytes, we might as well just do it!
// We `could` copy up to 64-bytes without any additional checks by using another SSE "loadu" & "storeu"
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
long long r1 = *(long long*)((char*)src + 16);
long long r2 = *(long long*)((char*)src + 24);
long long r3 = *(long long*)((char*)src + size - 16);
long long r4 = *(long long*)((char*)src + size - 8);
_mm_storeu_si128( (__m128i*)dst, xmm0 );
*(long long*)((char*)dst + 16) = r1;
*(long long*)((char*)dst + 24) = r2;
*(long long*)((char*)dst + size - 16) = r3;
*(long long*)((char*)dst + size - 8) = r4;
return dst;
}
if ( prealign >= 8 )
{
long long rax = *(long long*)src;
if ( prealign > 8 )
{
long long rcx = *(long long*)((char*)src + prealign - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + prealign - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( prealign >= 4 )
{
int eax = *(int*)src;
if ( prealign > 4 )
{
int ecx = *(int*)((char*)src + prealign - 4);
*(int*)dst = eax;
*(int*)((char*)dst + prealign - 4) = ecx;
}
else *(int*)dst = eax;
}
else
{
char al = *(char*)src;
if ( prealign > 1 )
{
short cx = *(short*)((char*)src + prealign - 2);
*(char*)dst = al;
*(short*)((char*)dst + prealign - 2) = cx;
}
else *(char*)dst = al;
}
src = (char*)src + prealign;
dst = (char*)dst + prealign;
size -= prealign;
}
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x20); // "Round down to nearest multiple of 32"
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
size -= offset; // "Remaining data after loop"
offset = -offset; // "Negative index from the end"
if ( ((size_t)src & 0xf) == 0 )
{
do
{
const __m128i xmm0 = _mm_load_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_load_si128( (__m128i*)((char*)src + offset + 16) );
_mm_store_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_store_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
} while ( offset += 32 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_load_si128( (__m128i*)src );
if ( size > 16 )
{
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_store_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
else
{
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
_mm_store_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_store_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
} while ( offset += 32 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
long long rax = *(long long*)((char*)src + size - 16);
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)((char*)dst + size - 16) = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
_mm_store_si128( (__m128i*)dst, xmm0 );
return (void*)ret;
}
}
}
else // do forward streaming copy/move
{
// Begin prefetching upto 4KB
for ( long long i = 0; i < 4096; i += 256 )
{
_mm_prefetch( ((char*)src + i), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + i + 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + i + 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + i + 192), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 64"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst + offset; // "Point to the end"
src = (char*)src + offset; // "Point to the end"
offset = -offset; // "Negative index from the end"
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset + 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
offset = -4096;
dst = (char*)dst + 4096;
src = (char*)src + 4096;
_mm_prefetch( ((char*)src + size - 64), _MM_HINT_NTA ); // prefetch the final tail section
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm3 );
} while ( offset += 64 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)src );
if ( size > 16 )
{
if ( size > 32 )
{
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + 16) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size - 32) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + 16), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 32), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size - 16) );
_mm_stream_si128( (__m128i*)dst, xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size - 16), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)dst, xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)src;
if ( size > 8 )
{
long long rcx = *(long long*)((char*)src + size - 8);
*(long long*)dst = rax;
*(long long*)((char*)dst + size - 8) = rcx;
}
else *(long long*)dst = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)src;
if ( size > 4 )
{
int ecx = *(int*)((char*)src + size - 4);
*(int*)dst = eax;
*(int*)((char*)dst + size - 4) = ecx;
}
else *(int*)dst = eax;
}
else if ( size >= 1 )
{
char al = *(char*)src;
if ( size > 1 )
{
short cx = *(short*)((char*)src + size - 2);
*(char*)dst = al;
*(short*)((char*)dst + size - 2) = cx;
}
else *(char*)dst = al;
}
return ret;
}
else // src < dst ... do reverse copy
{
src = (char*)src + size;
dst = (char*)dst + size;
const size_t prealign = (size_t)dst & 0xf;
if ( prealign )
{
if ( size <= 48 )
{
// prealignment might drop the remaining size below 32-bytes,
// we could also check "size - prealign <= 32", but since we're already here,
// and these statements can load upto 48-bytes, we might as well just do it!
// Actually, we can copy upto 64-bytes without any additional checks!
size = -size;
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) ); // first 32-bytes in reverse
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_storeu_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 ); // the "back" bytes are actually the base address!
return dst;
}
src = (char*)src - prealign;
dst = (char*)dst - prealign;
size -= prealign;
if ( prealign >= 8 )
{
long long rax = *(long long*)((char*)src + prealign - 8);
if ( prealign > 8 )
{
long long rcx = *(long long*)src;
*(long long*)((char*)dst + prealign - 8) = rax;
*(long long*)dst = rcx;
}
else *(long long*)dst = rax; // different on purpose, because we know the exact size now!
}
else if ( prealign >= 4 )
{
int eax = *(int*)((char*)src + prealign - 4);
if ( prealign > 4 )
{
int ecx = *(int*)src;
*(int*)((char*)dst + prealign - 4) = eax;
*(int*)dst = ecx;
}
else *(int*)dst = eax; // different on purpose!
}
else
{
char al = *(char*)((char*)src + prealign - 1);
if ( prealign > 1 )
{
short cx = *(short*)src;
*(char*)((char*)dst + prealign - 1) = al;
*(short*)dst = cx;
}
else *(char*)dst = al; // different on purpose!
}
}
if ( size < (1024 * 256) )
{
long long offset = (long long)(size & -0x20); // "Round down to nearest multiple of 32"
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
size -= offset; // "Remaining data after loop"
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 32; // MSVC completely re-engineers this!
if ( ((size_t)src & 0xf) == 0 )
{
do
{
const __m128i xmm0 = _mm_load_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm1 = _mm_load_si128( (__m128i*)((char*)src + offset) );
_mm_store_si128( (__m128i*)((char*)dst + offset + 16), xmm0 );
_mm_store_si128( (__m128i*)((char*)dst + offset), xmm1 );
} while ( (offset -= 32) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_load_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
size = -size;
//const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) ); // SSE2 alternative
long long rax = *(long long*)((char*)src + size + 8);
long long rcx = *(long long*)((char*)src + size);
//_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
*(long long*)((char*)dst + size + 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
_mm_store_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
else
{
do
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_store_si128( (__m128i*)((char*)dst + offset + 16), xmm0 );
_mm_store_si128( (__m128i*)((char*)dst + offset), xmm1 );
} while ( (offset -= 32) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
size = -size;
long long rax = *(long long*)((char*)src + size + 8);
long long rcx = *(long long*)((char*)src + size);
*(long long*)((char*)dst + size + 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
_mm_store_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
}
else // do reversed streaming copy/move
{
// Begin prefetching upto 4KB
for ( long long offset = 0; offset > -4096; offset -= 256 )
{
_mm_prefetch( ((char*)src + offset - 64), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 128), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 192), _MM_HINT_NTA );
_mm_prefetch( ((char*)src + offset - 256), _MM_HINT_NTA );
}
long long offset = (long long)(size & -0x40); // "Round down to nearest multiple of 32"
size -= offset; // "Remaining data after loop"
offset -= 4096; // stage 1 INCLUDES prefetches
dst = (char*)dst - offset; // "Point to the end" ... actually, we point to the start!
src = (char*)src - offset; // "Point to the end" ... actually, we point to the start!
//offset = -offset; // "Negative index from the end" ... not when doing reverse copy/move!
offset -= 64;
do // stage 1 ~~ WITH prefetching
{
_mm_prefetch( (char*)src + offset - 4096, _MM_HINT_NTA );
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
offset = 4096;
dst = (char*)dst - 4096;
src = (char*)src - 4096;
_mm_prefetch( ((char*)src - 64), _MM_HINT_NTA ); // prefetch the final tail section
offset -= 64;
do // stage 2 ~~ WITHOUT further prefetching
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 48) );
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 32) );
const __m128i xmm2 = _mm_loadu_si128( (__m128i*)((char*)src + offset + 16) );
const __m128i xmm3 = _mm_loadu_si128( (__m128i*)((char*)src + offset) );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 48), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 32), xmm1 );
_mm_stream_si128( (__m128i*)((char*)dst + offset + 16), xmm2 );
_mm_stream_si128( (__m128i*)((char*)dst + offset), xmm3 );
} while ( (offset -= 64) >= 0 );
if ( size >= 16 )
{
const __m128i xmm0 = _mm_loadu_si128( (__m128i*)((char*)src - 16) );
if ( size > 16 )
{
if ( size > 32 )
{
size = -size;
const __m128i xmm1 = _mm_loadu_si128( (__m128i*)((char*)src - 32) );
const __m128i xmm6 = _mm_loadu_si128( (__m128i*)((char*)src + size + 16) );
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_stream_si128( (__m128i*)((char*)dst - 32), xmm1 );
_mm_storeu_si128( (__m128i*)((char*)dst + size + 16), xmm6 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
size = -size;
const __m128i xmm7 = _mm_loadu_si128( (__m128i*)((char*)src + size) );
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
_mm_storeu_si128( (__m128i*)((char*)dst + size), xmm7 );
return ret;
}
_mm_stream_si128( (__m128i*)((char*)dst - 16), xmm0 );
return ret;
}
}
if ( size >= 8 )
{
long long rax = *(long long*)((char*)src - 8);
if ( size > 8 )
{
size = -size; // that's right, we're converting an unsigned value to a negative, saves 2 clock cycles!
long long rcx = *(long long*)((char*)src + size);
*(long long*)((char*)dst - 8) = rax;
*(long long*)((char*)dst + size) = rcx;
}
else *(long long*)((char*)dst - 8) = rax;
}
else if ( size >= 4 )
{
int eax = *(int*)((char*)src - 4);
if ( size > 4 )
{
size = -size;
int ecx = *(int*)((char*)src + size);
*(int*)((char*)dst - 4) = eax;
*(int*)((char*)dst + size) = ecx;
}
else *(int*)((char*)dst - 4) = eax;
}
else if ( size >= 1 )
{
char al = *((char*)src - 1);
if ( size > 1 )
{
size = -size;
short cx = *(short*)((char*)src + size);
*((char*)dst - 1) = al;
*(short*)((char*)dst + size) = cx;
}
else *((char*)dst - 1) = al;
}
return ret;
}
}
}
#endif // end test for 32-bit
#endif // end test for Intel/AMD (32-bit & 64-bit)
#if defined(_MSC_VER)
#pragma warning( pop )
#endif
void* APEXCALL memmove_dispatcher( void *dst, const void *src, size_t size )
{
#if (defined(_M_X64) || defined(__x86_64__) || defined(__i386) || defined(_M_IX86)) && (defined(_MSC_VER) || defined(__GNUC__)) // Compiler and architecture test (Intel/AMD Architecture)! Visual Studio and GCC / LLVM (Clang)
#if defined(_MSC_VER)
int cpuid[4] = {-1}; // Visual Studio
__cpuid( cpuid, 1 );
#define bit_SSE2 (1 << 26) // Taken from GCC <cpuid.h> ... just more visual & descriptive!
#define bit_SSSE3 (1 << 9)
#define bit_SSE4_2 (1 << 20)
#else
unsigned int cpuid[4]; // GCC / LLVM (Clang)
__get_cpuid(1, &cpuid[0], &cpuid[1], &cpuid[2], &cpuid[3]);
#endif
#if defined(_M_X64) || defined(__x86_64__) // 64-bit
if ( cpuid[2] & bit_SSE4_2 ) // detect SSE4.2, available on Core i and newer processors, they include "fast unaligned" memory access
apex::memcpy = apex::memmove = &apex::kryptonite;
else
apex::memcpy = apex::memmove = &apex::tiberium;
#else // 32-bit
if ( cpuid[2] & bit_SSE4_2 ) // detect SSE4.2, available on Core i and newer processors, they include "fast unaligned" memory access
apex::memcpy = apex::memmove = &apex::kryptonite;
else if ( cpuid[2] & bit_SSSE3 ) // detect SSSE3, available on Core/Core 2 and newer
apex::memcpy = apex::memmove = &apex::tiberium; // `tiberium` CAN run with the SSE2 instructions alone, however there was something about very old SSE2 (only) computers, some penalty when using `tiberiums` algorithm, so I've restricted `tiberium` to Core/Core 2 based machines on 32-bit by doing this!
else if ( cpuid[3] & bit_SSE2 )
apex::memcpy = apex::memmove = &apex::mithril; // this is for very, very old computers with SSE2 only! eg. old Pentium 4! There was something about computers WITHOUT SSSE3 (Core microarchitecture) that made `tiberium` a bit slower. So this is for super old (P4) PC's!
else {
apex::memcpy = &::memcpy; // No SSE2 no cry!
apex::memmove = &::memmove;
}
#endif
#else // unknown compiler or architecture! eg. __arm__ / __mips__ / __ppc__ / __sparc / __ia64 (Itanium) etc.
#if defined(__x86_64__)
apex::memcpy = apex::memmove = &apex::tiberium; // unknown compiler BUT it declared support for Intel/AMD x64/AMD64 (64-bit), so it should come with the <emmintrin.h> file from Intel! 64-bit x64/AMD64 includes SSE2! This includes `Portland (PGCC/PGCPP)`, `Oracle Solaris Studio` and `Intel compiler (ICC)`! I don't have code for CPUID for these compilers so I don't know how to check for SSE2/SSSE3/SSE4.2 on them!
#else
apex::memcpy = &::memcpy; // unknown compiler or architecture!
apex::memmove = &::memmove;
#endif
#endif
return apex::memmove( dst, src, size ); // safe to call memmove even for memcpy!
}
void *(APEXCALL *memcpy)( void *dst, const void *src, size_t size ) = apex::memmove_dispatcher;
void *(APEXCALL *memmove)( void *dst, const void *src, size_t size ) = apex::memmove_dispatcher;
}
\ No newline at end of file
#ifndef __APEX_MEMMOVE_H__
#define __APEX_MEMMOVE_H__
// apex_memmove written by Trevor Herselman in 2014
// FORCE `CDECL` calling convention on 32-bit builds on our function pointers, because we need it to match the original `std::memmove` definition; in-case the user specified a different default function calling convention! (I specified __fastcall as my default calling convention and got errors! So I needed to add this!)
#if !defined(__x86_64__) && !defined(_M_X64) && (defined(__i386) || defined(_M_IX86)) && (defined(_MSC_VER) || defined(__GNUC__))
#if defined(_MSC_VER)
#define APEXCALL __cdecl // 32-bit on Visual Studio
#else
#define APEXCALL __attribute__((__cdecl__)) // 32-bit on GCC / LLVM (Clang)
#endif
#else
#define APEXCALL // 64-bit - __fastcall is default on 64-bit!
#endif
#ifdef __cplusplus
#include <cstddef> // for `size_t`
namespace apex
{
extern void *(APEXCALL *memcpy)( void *dst, const void *src, size_t size );
extern void *(APEXCALL *memmove)( void *dst, const void *src, size_t size );
}
#define apex_memcpy apex::memcpy
#define apex_memmove apex::memmove
#else
#include <stddef.h> // ANSI/ISO C - for `size_t`
extern void *(APEXCALL *apex_memcpy)( void *dst, const void *src, size_t size );
extern void *(APEXCALL *apex_memmove)( void *dst, const void *src, size_t size );
#endif // __cplusplus
#endif // __APEX_MEMMOVE_H__
\ No newline at end of file
#pragma once
#include<string>
#include<memory>
#include<map>
#include<vector>
//////////////////////////////////////////////////////////////////////////////////////////////////
///
///
///
///
///
///
///
///
///
///
///
#ifndef NO_AUTOLINK_NADS_DDS_LIB
#ifdef _MSC_VER
#ifdef _DEBUG
#ifdef _X86_
#ifndef NADSDDDS_DLL
#pragma comment(lib,"NadsDDSLib_32ds.lib")
#pragma comment(lib,"nddscpp2zd.lib")
#pragma comment(lib,"nddsczd.lib")
#pragma comment(lib,"nddscorezd.lib")
#pragma comment(lib,"netapi32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"user32.lib")
#endif
#else
#ifndef NADSDDDS_DLL
#pragma comment(lib,"NadsDDSLib_64ds.lib")
#pragma comment(lib,"nddscpp2zd.lib")
#pragma comment(lib,"nddsczd.lib")
#pragma comment(lib,"nddscorezd.lib")
#pragma comment(lib,"netapi32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"user32.lib")
#endif
#endif // DEBUG
#endif
#endif
#endif
namespace NADSDDS {
using namespace std;
class CellRoot;
class CFloatPub;
class CCharPub;
class CDoublePub;
class CIntPub;
class CShortPub;
typedef unique_ptr< CellRoot> TPubPtr;
typedef unique_ptr< CFloatPub> TFloatPubPtr ;
typedef unique_ptr< CCharPub> TCharPubPtr;
typedef unique_ptr< CDoublePub> TDoublePubPtr;
typedef unique_ptr< CIntPub> TIntPubPtr;
typedef unique_ptr< CShortPub> TShortPubPtr;
class CellRoot {
public:
CellRoot(int id) :_eid(id), _itemCount(0), _period(-1) {
}
virtual void* Raw() = 0;
virtual void Send() = 0;
virtual int& eid() = 0;
int _eid;
std::string _name;
size_t _itemCount;
size_t _sizeInBytes;
int _period;
};
class CellInRoot {
public:
CellInRoot(const std::string& name) :_name(name),_eid(-1), _itemCount(0), _period(-1), _sizeInBytes(0){
}
virtual void* Raw() = 0;
virtual int eid() = 0;
int _eid;
std::string _name;
size_t _itemCount;
size_t _sizeInBytes;
int _period;
};
template<class T> class BufferedCellRoot: public CellInRoot {
public:
BufferedCellRoot(std::string name) : CellInRoot(name) {}
vector<T>& operator()() {
return _buffer;
}
virtual bool Swap() = 0;
vector<T>& GetBuff() { return _buffer; }
size_t Size() { return _buffer.size(); }
virtual void* Raw() { return _buffer.data(); }
protected:
vector<T> _buffer;
};
class CSubscription {
public:
typedef unique_ptr<CSubscription> TRef;
static TRef MakeSubscription(const std::string&, char cellType);
virtual const char* asChar() = 0;
virtual const double* asDouble() = 0;
virtual const float* asFloat() = 0;
virtual const int* asInt() = 0;
virtual const short* asShort() = 0;
virtual void SwapBuffer() = 0;
size_t GetSizeInByes();
void* GetRaw();
protected:
virtual CellInRoot* GetCell() = 0;
};
class CFloatSubscription : public CSubscription {
public:
typedef unique_ptr<BufferedCellRoot<float>> TSubref;
CFloatSubscription(TSubref&& sub) :_subsription(std::move(sub)) {};
virtual const float* asFloat() override { if (_subsription->Size() == 0) return nullptr; return _subsription->GetBuff().data(); };
virtual const char* asChar() { return nullptr; };
virtual const double* asDouble() { return nullptr; };
virtual const int* asInt() { return nullptr; };
virtual const short* asShort() { return nullptr; };
std::vector<float>& operator()() { return _subsription->GetBuff(); };
virtual void SwapBuffer() override { _subsription->Swap(); };
protected:
virtual CellInRoot* GetCell() override { return _subsription.get(); };
private:
TSubref _subsription;
};
class CIntSubscription : public CSubscription {
public:
typedef unique_ptr<BufferedCellRoot<int>> TSubref;
CIntSubscription(TSubref&& sub) :_subsription(std::move(sub)) {};
virtual const float* asFloat() override {return nullptr;};
virtual const char* asChar() { return nullptr; };
virtual const double* asDouble() { return nullptr; };
virtual const int* asInt() { if (_subsription->Size() == 0) return nullptr; return _subsription->GetBuff().data(); };
virtual const short* asShort() { return nullptr; };
std::vector<int>& operator()() { return _subsription->GetBuff(); };
virtual void SwapBuffer() override { _subsription->Swap(); };
protected:
virtual CellInRoot* GetCell() override { return _subsription.get(); };
private:
TSubref _subsription;
};
class CDoubleSubscription : public CSubscription {
public:
typedef unique_ptr<BufferedCellRoot<double>> TSubref;
CDoubleSubscription(TSubref&& sub) :_subsription(std::move(sub)) {};
virtual const float* asFloat() override { return nullptr; };
virtual const char* asChar() { return nullptr; };
virtual const double* asDouble() { if (_subsription->Size() == 0) return nullptr; return _subsription->GetBuff().data(); };
virtual const int* asInt() { return nullptr; };
virtual const short* asShort() { return nullptr; };
std::vector<double>& operator()() { return _subsription->GetBuff(); };
virtual void SwapBuffer() override { _subsription->Swap(); };
protected:
virtual CellInRoot* GetCell() override { return _subsription.get(); };
private:
TSubref _subsription;
};
class CCharSubscription : public CSubscription {
public:
typedef unique_ptr<BufferedCellRoot<char>> TSubref;
CCharSubscription(TSubref&& sub) :_subsription(std::move(sub)) {};
virtual const float* asFloat() override { return nullptr; };
virtual const char* asChar() { if (_subsription->Size() == 0) return nullptr; return _subsription->GetBuff().data(); }
virtual const double* asDouble() { return nullptr; };
virtual const int* asInt() { return nullptr; };
virtual const short* asShort() { return nullptr; };
std::vector<char>& operator()() { return _subsription->GetBuff(); };
virtual void SwapBuffer() override { _subsription->Swap(); };
protected:
virtual CellInRoot* GetCell() override { return _subsription.get(); };
private:
TSubref _subsription;
};
class CShortSubscription : public CSubscription {
public:
typedef unique_ptr<BufferedCellRoot<short>> TSubref;
CShortSubscription(TSubref&& sub) :_subsription(std::move(sub)) {};
virtual const float* asFloat() override { return nullptr; };
virtual const char* asChar() { return nullptr; }
virtual const double* asDouble() { return nullptr; };
virtual const int* asInt() { return nullptr; };
virtual const short* asShort() { if (_subsription->Size() == 0) return nullptr; return _subsription->GetBuff().data(); };
std::vector<short>& operator()() { return _subsription->GetBuff(); };
virtual void SwapBuffer() override { _subsription->Swap(); };
protected:
virtual CellInRoot* GetCell() override { return _subsription.get(); };
private:
TSubref _subsription;
};
//class CDoubleSubscrition : public CSubscription {
//public:
// CDoubleSubscrition();
// std::vector<double>& operator()() { return _val->GetBuff(); };;
//private:
// unique_ptr<BufferedCellRoot<double>> _val;
//};
//class CIntSubscription : public CSubscription {
//public:
// CIntSubscription();
// std::vector<int>& operator()() { return _val->GetBuff(); };
//private:
// unique_ptr<BufferedCellRoot<int>> _val;
//};
//class CCharSubscription : public CSubscription {
//public:
// CCharSubscription();
// std::vector<char>& operator()() { return _val->GetBuff(); };
//private:
// unique_ptr<BufferedCellRoot<char>> _val;
//};
//class CShortSubscription : public CSubscription {
//public:
// CShortSubscription();
// std::vector<short>& operator()() { return _val->GetBuff(); };
//private:
// unique_ptr<BufferedCellRoot<short>> _val;
//};
class CPublication{
public:
typedef unique_ptr<CPublication> TRef;
static TRef MakePublication(const std::string&, int EID, size_t count, char cellType);
virtual char* asChar();
virtual double* asDouble();
virtual float* asFloat();
virtual int* asInt();
virtual short* asShort();
void* Raw();
const std::string& Name();
int EID();
size_t SizeInBytes();
size_t Count();
virtual void Publish() = 0 ;
protected:
virtual CellRoot* GetPub() = 0;
CPublication() {};
};
class DoublePublication :public CPublication {
public:
DoublePublication(TDoublePubPtr&&);
virtual double* asDouble() override;
DoublePublication& operator= (double);
double& operator[] (size_t);
virtual void Publish() override;
private:
virtual CellRoot* GetPub() override;
TDoublePubPtr _ref;
};
class FloatPublication :public CPublication {
public:
FloatPublication(TFloatPubPtr&&);
virtual float* asFloat() override;
FloatPublication& operator= (float);
float& operator[] (size_t);
virtual void Publish() override;
private:
virtual CellRoot* GetPub() override;
TFloatPubPtr _ref;
};
class ShortPublication :public CPublication {
public:
ShortPublication(TShortPubPtr&&);
virtual short* asShort() override;
ShortPublication& operator= (short);
short& operator[] (size_t);
virtual void Publish() override;
private:
virtual CellRoot* GetPub() override;
TShortPubPtr _ref;
};
class IntPublication :public CPublication {
public:
IntPublication(TIntPubPtr&&);
virtual int* asInt() override;
IntPublication& operator= (int);
int& operator[] (size_t);
virtual void Publish() override;
private:
virtual CellRoot* GetPub() override;
TIntPubPtr _ref;
};
class CharPublication :public CPublication {
public:
CharPublication(TCharPubPtr&&);
virtual char* asChar() override;
CharPublication& operator= (const std::string&);
char& operator[] (size_t);
virtual void Publish() override;
private:
virtual CellRoot* GetPub() override;
TCharPubPtr _ref;
};
namespace Info {
typedef std::tuple<std::string, char> TCellInfo;
typedef std::vector<TCellInfo> TCellInfoVec;
void GetCellInfo(TCellInfoVec& cells);
}
class CBPriv;
class CState {
public:
friend class CBPriv;
class Callback {
public:
Callback() {};
virtual void OnFrame(int frame) = 0;
};
typedef std::shared_ptr<Callback> TCBRef;
typedef std::weak_ptr<Callback> TCBWRef;
CState();
~CState();
int GetFrame();
int GetState();
void Register(TCBRef);
protected:
void NewFrame(int);
typedef std::shared_ptr<CBPriv> TCBPrivRef;
TCBPrivRef _privCB;
typedef std::vector<TCBWRef> TCBWRefs;
TCBWRefs _Cbs;
};
}
\ No newline at end of file
#pragma once
#include<string>
#include<memory>
#include<map>
#include<vector>
//////////////////////////////////////////////////////////////////////////////////////////////////
///
///
///
///
///
///
///
///
///
///
///
namespace NADSDDS {
using namespace std;
class CellRoot;
class CFloatPub;
class CCharPub;
class CDoublePub;
class CIntPub;
class CShortPub;
typedef unique_ptr< CellRoot> TPubPtr;
typedef unique_ptr< CFloatPub> TFloatPubPtr ;
typedef unique_ptr< CCharPub> TCharPubPtr;
typedef unique_ptr< CDoublePub> TDoublePubPtr;
typedef unique_ptr< CIntPub> TIntPubPtr;
typedef unique_ptr< CShortPub> TShortPubPtr;
class CellRoot {
public:
CellRoot(int id) :_eid(id), _itemCount(0), _period(-1) {
}
virtual void* Raw() = 0;
virtual void Send() = 0;
virtual int& eid() = 0;
int _eid;
std::string _name;
size_t _itemCount;
size_t _sizeInBytes;
int _period;
};
class CellInRoot {
public:
CellInRoot(const std::string& name) :_name(name),_eid(-1), _itemCount(0), _period(-1) {
}
virtual void* Raw() = 0;
virtual int eid() = 0;
int _eid;
std::string _name;
size_t _itemCount;
size_t _sizeInBytes;
int _period;
};
template<class T> class BufferedCellRoot: public CellInRoot {
public:
BufferedCellRoot(std::string name) : CellInRoot(name) {}
vector<T>& operator()() {
return _buffer;
}
virtual bool Swap() = 0;
vector<T>& GetBuff() { return _buffer; }
virtual void* Raw() { return _buffer.data(); }
protected:
vector<T> _buffer;
};
class CSubscription {
public:
typedef unique_ptr<CSubscription> TRef;
TRef MakeSubscription(const std::string&, int EID, size_t count, char cellType);
virtual const char* asChar() { return nullptr; };
virtual const double* asDouble() { return nullptr; };
virtual const float* asFloat() { return nullptr; };
virtual const int* asInt() { return nullptr; };
virtual const short* asShort() { return nullptr; };
virtual void SwapBuffer() = 0;
protected:
virtual CellInRoot* GetCell() = 0;
};
class CFloatSubscription : public CSubscription {
public:
typedef unique_ptr<BufferedCellRoot<float>> TSubref;
CFloatSubscription(TSubref&& sub) :_subsription(std::move(sub)) {};
virtual const float* asFloat() override { return _subsription->GetBuff().data(); };
std::vector<float>& operator()() { return _subsription->GetBuff(); };
virtual void SwapBuffer() override { _subsription->Swap(); };
protected:
virtual CellInRoot* GetCell() override { return _subsription.get(); };
private:
TSubref _subsription;
};
//class CDoubleSubscrition : public CSubscription {
//public:
// CDoubleSubscrition();
// std::vector<double>& operator()() { return _val->GetBuff(); };;
//private:
// unique_ptr<BufferedCellRoot<double>> _val;
//};
//class CIntSubscription : public CSubscription {
//public:
// CIntSubscription();
// std::vector<int>& operator()() { return _val->GetBuff(); };
//private:
// unique_ptr<BufferedCellRoot<int>> _val;
//};
//class CCharSubscription : public CSubscription {
//public:
// CCharSubscription();
// std::vector<char>& operator()() { return _val->GetBuff(); };
//private:
// unique_ptr<BufferedCellRoot<char>> _val;
//};
//class CShortSubscription : public CSubscription {
//public:
// CShortSubscription();
// std::vector<short>& operator()() { return _val->GetBuff(); };
//private:
// unique_ptr<BufferedCellRoot<short>> _val;
//};
class CPublication{
public:
typedef unique_ptr<CPublication> TRef;
TRef MakePublication(const std::string&, int EID, size_t count, char cellType);
virtual char* asChar();
virtual double* asDouble();
virtual float* asFloat();
virtual int* asInt();
virtual short* asShort();
void* Raw();
const std::string& Name();
int EID();
size_t SizeInBytes();
size_t Count();
void Publish();
protected:
virtual CellRoot* GetPub() = 0;
CPublication() {};
};
class DoublePublication :public CPublication {
public:
DoublePublication(TDoublePubPtr&&);
virtual double* asDouble()override;
DoublePublication& operator= (double);
double& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TDoublePubPtr _ref;
};
class FloatPublication :public CPublication {
public:
FloatPublication(TFloatPubPtr&&);
virtual float* asFloat() override;
FloatPublication& operator= (float);
float& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TFloatPubPtr _ref;
};
class ShortPublication :public CPublication {
public:
ShortPublication(TShortPubPtr&&);
virtual short* asShort() override;
ShortPublication& operator= (short);
short& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TShortPubPtr _ref;
};
class IntPublication :public CPublication {
public:
IntPublication(TIntPubPtr&&);
virtual int* asInt() override;
IntPublication& operator= (int);
int& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TIntPubPtr _ref;
};
class CharPublication :public CPublication {
public:
CharPublication(TCharPubPtr&&);
virtual char* asChar() override;
CharPublication& operator= (const std::string&);
char& operator[] (size_t);
private:
virtual CellRoot* GetPub() override;
TCharPubPtr _ref;
};
}
\ No newline at end of file
/*
/ (c) Copyright 2018, Real-Time Innovations, All rights reserved. /
/ /
/ RTI grants Licensee a license to use, modify, compile, and create /
/ derivative works of the software solely for use with RTI Connext DDS. /
/ Licensee may redistribute copies of the software provided that all such /
/ copies are subject to this license. The software is provided "as is", with /
/ no warranty of any type, including any warranty for fitness for any purpose. /
/ RTI is under no obligation to maintain or support the software. RTI shall /
/ not be liable for any incidental or consequential damages arising out of the /
/ use or inability to use the software. /
*/
#include "GenericSubscriber.h"
#include "value_as_string.h"
#include <dds/topic/BuiltinTopic.hpp>
#include <optional>
#include <rti/config/Version.hpp>
#include <rti/core/ListenerBinder.hpp>
#include <rti/topic/PrintFormat.hpp>
#include <rti/topic/rtitopic.hpp>
using namespace dds::core;
using namespace dds::core::status;
using namespace dds::domain;
using namespace dds::topic;
using namespace dds::sub;
using namespace dds::pub;
using kind = xtypes::TypeKind_def;
namespace NADSDDS {
/**
* @brief GenericSubscriber class. Can be instantiated with only a participant or
* with a participant and a type. If instantiated without a type then DDS pro is
* assumed and the type will be discovered.
*
*/
class GenericSubscriber::GenericSubscriberImpl : public NoOpDataReaderListener<xtypes::DynamicData>
{
private:
using GenericTopic = Topic<xtypes::DynamicData>;
using GenericReader = DataReader<xtypes::DynamicData>;
using TopicName = std::string;
using TopicType = optional<xtypes::DynamicType>;
using TopicAndType = std::tuple<TopicName, TopicType>;
using TopicAndTypeList = std::vector<TopicAndType>;
using TopicColumnName = std::string;
using TopicColumnType = xtypes::DynamicType;
using TopicColumnKey = bool;
using TopicColumnOptional = bool;
using TopicColumn = std::tuple<TopicColumnName, TopicColumnType, TopicColumnKey, TopicColumnOptional>;
using TopicColumnList = std::vector<TopicColumn>;
GenericSubscriberImpl(const GenericSubscriberImpl&) = delete; // non construction-copyable
GenericSubscriberImpl& operator=(const GenericSubscriberImpl&) = delete; // non copyable
// class used to gather topics from default publisher
class MyReaderListener : public NoOpDataReaderListener<PublicationBuiltinTopicData> {
public:
explicit MyReaderListener(TopicAndTypeList& topics) :m_topics(topics)
{
}
// incoming data on the builtin topic reader
void on_data_available(DataReader<PublicationBuiltinTopicData>& rdr) override
{
LoanedSamples<PublicationBuiltinTopicData> samples = rdr.take();
for (auto& sample : samples) {
if (sample.info().valid()) {
m_topics.emplace_back(sample.data().topic_name(), sample.data()->type());
}
}
}
private:
TopicAndTypeList & m_topics;
};
// wait until the list of topics has been populated
void wait_for_discovery() const
{
while (m_discovered_topics.empty()) {
rti::util::sleep(Duration::from_secs(poll_seconds));
}
}
template<typename Funct>
void process_members(const xtypes::StructType& record, Funct func) const
{
for (auto& member : record.members()) {
func(member);
}
}
// get all of the columns (i.e. members) of the topic type
void get_topic_columns(const TopicType& topic_type)
{
if (!m_columns.empty()) {
return;
}
auto& record = static_cast<const xtypes::StructType&>(topic_type.get());
if (xtypes::is_extensible(record) && record.has_parent()) {
// get the base members since this is an extensible type
process_members(record.parent(),
[this](const xtypes::Member& member) {
m_columns.emplace_back(member.name(), member.type(),
member.is_key(), member.is_optional());
});
}
process_members(record,
[this](const xtypes::Member& member) {
m_columns.emplace_back(member.name(), member.type(),
member.is_key(), member.is_optional());
});
}
std::string padding(size_t size, const char c)
{
return std::string(size, c);
}
// incoming data from the topic we subscribed to
void on_data_available(DataReader<xtypes::DynamicData>& rdr) override
{
LoanedSamples<xtypes::DynamicData> samples = rdr.take();
for (auto& sample : samples) {
if (sample.info().valid()) {
for (auto& column : m_columns) {
int column_width = (std::get<1>(column).kind() == kind::SEQUENCE_TYPE ||
std::get<1>(column).kind() == kind::AGGREGATION_TYPE ||
std::get<1>(column).kind() == kind::STRUCTURE_TYPE) ? data_row_agg_width :
data_row_sim_width;
std::cout << padding(column_width - data_row_width_off, ' ')
<< std::setw(column_width)
<< value_as_string(sample.data(), std::get<0>(column));
}
std::cout << std::endl;
}
}
}
// print out header based on discovered topic type members
void header(const TopicType& topic_type)
{
get_topic_columns(topic_type);
std::cout << " ";
for (auto& column : m_columns) {
int column_width = (std::get<1>(column).kind() == kind::SEQUENCE_TYPE ||
std::get<1>(column).kind() == kind::AGGREGATION_TYPE ||
std::get<1>(column).kind() == kind::STRUCTURE_TYPE) ? hdr_row_agg_width :
hdr_row_sim_width;
std::cout << std::setw(column_width)
<< std::get<0>(column)
<< padding(column_width - hdr_row_width_off, ' ') << "|";
}
std::cout << std::endl;
}
public:
GenericSubscriberImpl(DomainParticipant& participant, bool verbose) : m_participant(participant),
m_ear(m_discovered_topics),
m_verbose(verbose)
{
std::vector<DataReader<PublicationBuiltinTopicData>> rdr_list;
// locate the built-in subscriber for the topic names
find<DataReader<PublicationBuiltinTopicData>>(builtin_subscriber(m_participant),
dds::topic::publication_topic_name(),
std::back_inserter(rdr_list));
// attach listener to all readers
for (auto& rdr : rdr_list) {
rdr.listener(&m_ear.value(), StatusMask::data_available());
}
// only now that we have our listeners attached are we ready to enable the participant
m_participant.enable();
}
GenericSubscriberImpl(DomainParticipant& participant,
const xtypes::StructType& topic_type,
bool verbose) : m_topic_type(topic_type),
m_participant(participant),
m_verbose(verbose)
{
m_participant.enable();
}
void list_topics(TTopics & in)
{
wait_for_discovery();
std::cout << "Number of topics discovered: " << m_discovered_topics.size() << std::endl;
for (auto topic : m_discovered_topics) {
if (std::get<1>(topic)) {
in.push_back(TNameTypePair(
std::get<0>(topic),
std::get<1>(topic).get().name()));
}
else {
in.push_back(TNameTypePair(
std::get<0>(topic),
string("unkown")));
}
}
}
void receive(const TopicName& topic_name)
{
TopicType topic_type;
if (m_ear) {
wait_for_discovery();
for (auto topic : m_discovered_topics) {
if (std::get<0>(topic) == topic_name) {
if ((topic_type = std::get<1>(topic))) {
std::cout << "Enabling subscribing on topic " << topic_name
<< " which is of type " << topic_type.get().name() << std::endl;
break; // only support subscribing to a single topic
}
}
}
if (!topic_type) {
throw TopicNotFound(topic_name);
}
}
else {
topic_type = m_topic_type;
}
GenericReader reader(Subscriber(m_participant),
GenericTopic(m_participant, topic_name, topic_type.get()));
if (reader.is_nil()) {
throw ReaderNotCreated();
}
auto scoped_listener = rti::core::bind_listener(reader, this,
dds::core::status::StatusMask::data_available());
// display headers
header(topic_type);
// while there are writers available collect and display data
while (true) {
rti::util::sleep(Duration::from_secs(poll_seconds));
}
}
private:
TopicAndTypeList m_discovered_topics;
TopicType m_topic_type;
DomainParticipant& m_participant;
std::optional<MyReaderListener> m_ear = std::nullopt;
bool m_verbose;
TopicColumnList m_columns;
static const int poll_seconds = 1;
static const uint8_t data_row_agg_width = 33;
static const uint8_t data_row_sim_width = 16;
static const uint8_t hdr_row_agg_width = 30;
static const uint8_t hdr_row_sim_width = 15;
static const uint8_t data_row_width_off = 14;
static const uint8_t hdr_row_width_off = 8;
};
GenericSubscriber::GenericSubscriber(DomainParticipant& participant, bool verbose)
: impl(std::make_unique<GenericSubscriberImpl>(participant, verbose))
{
}
GenericSubscriber::GenericSubscriber(DomainParticipant& participant, const xtypes::StructType& topic_type,
bool verbose)
: impl(std::make_unique<GenericSubscriberImpl>(participant, topic_type, verbose))
{
}
GenericSubscriber::~GenericSubscriber() = default;
void GenericSubscriber::list_topics(TTopics& in)
{
impl->list_topics(in);
}
void GenericSubscriber::receive(const std::string& topic_name)
{
impl->receive(topic_name);
}
}
\ No newline at end of file
/********************************************************************************/
/* (c) Copyright 2018, Real-Time Innovations, All rights reserved. */
/* */
/* RTI grants Licensee a license to use, modify, compile, and create */
/* derivative works of the software solely for use with RTI Connext DDS. */
/* Licensee may redistribute copies of the software provided that all such */
/* copies are subject to this license. The software is provided "as is", with */
/* no warranty of any type, including any warranty for fitness for any purpose. */
/* RTI is under no obligation to maintain or support the software. RTI shall */
/* not be liable for any incidental or consequential damages arising out of the */
/* use or inability to use the software. */
/********************************************************************************/
#ifndef __GENERIC_SUBSCRIBER__
#define __GENERIC_SUBSCRIBER__
#include <dds/dds.hpp>
#include <string>
namespace NADSDDS {
/**
* A GenericSubscriber requires the factory to be configured to
* create entities in a disabled state prior to instantiation.
* It will not function otherwise.
*/
class GenericSubscriber {
public:
/**
* @brief Exception thrown when client supplied topic name can not be found in domain
*
*/
class TopicNotFound : std::exception
{
public:
/**
* @brief Construct a new Topic Not Found object
*
* @param topic_name name of the topic that was not found
*/
TopicNotFound(const std::string& topic_name) : m_topic_name(topic_name)
{
}
/**
* @brief Retrieve a const char* pointing to the name of the topic that was not found
*
* @return const char*
*/
const char* what(void) const noexcept override
{
return m_topic_name.c_str();
}
private:
std::string m_topic_name;
};
/**
* @brief Exception thrown when a reader cannot be created for the specified topic
*
*/
class ReaderNotCreated : std::exception
{
public:
/**
* @brief Construct a new Reader Not Created object
*
*/
ReaderNotCreated()
{
}
};
/**
* @brief Construct a new Generic Subscriber Impl object
*
* @param participant participant under which the subscriber will be created
* @param verbose enable verbose logging
*/
GenericSubscriber(dds::domain::DomainParticipant& participant,
bool verbose);
/**
* @brief Construct a new Generic Subscriber Impl object
*
* @param participant participant under which the subscriber will be created
* @param topic_type datatype (for the topic name which will be supplied to receive)
* @param verbose enable verbose logging
*/
GenericSubscriber(dds::domain::DomainParticipant& participant,
const dds::core::xtypes::StructType& topic_type,
bool verbose);
/**
* Subscriber destructor
*/
~GenericSubscriber();
/**
* @brief list topics available in participants domain
*
*
*/
typedef std::pair<std::string, std::string> TNameTypePair;
typedef std::vector<TNameTypePair> TTopics;
void list_topics(TTopics&);
/**
* @brief begin receiving data
*
* @param topic_name topic on which to receive data
*/
void receive(const std::string& topic_name);
private:
class GenericSubscriberImpl;
std::unique_ptr<GenericSubscriberImpl> impl{};
};
}
#endif
\ No newline at end of file
#include "stdafx.h"
#include "nadsddsimpl.h"
using namespace std;
namespace NADSDDS {
DDSDomainRepo::TRef DDSDomainRepo::DDSDomainRepo::_self;
dds::domain::DomainParticipant&
DDSDomainRepo::GetDomain(int id) {
if (!_self) {
auto ptr = new DDSDomainRepo();
_self = TRef(ptr);
}
auto itr = _self->_DomainRefs.find(id);
if (itr == _self->_DomainRefs.end())
{
_self->_DomainRefs[id] = make_unique<dds::domain::DomainParticipant>(id);
return *(_self->_DomainRefs[id]);
}
return *(itr->second);
}
DDSDomainRepo::DDSDomainRepo() {
};
DDSTopicInfo::TRef DDSTopicInfo::_self;
DDSTopicInfo* DDSTopicInfo::Get() {
if (!_self) {
auto ptr = new DDSTopicInfo();
_self = TRef(ptr);
}
return _self.get();
}
void DDSTopicInfo::Refresh() {
DDSTopicInfo::Get()->RefreshImpl();
}
void DDSTopicInfo::RefreshImpl() {
dds::domain::qos::DomainParticipantQos participant_qos = dds::core::QosProvider::Default().participant_qos();
dds::domain::qos::DomainParticipantFactoryQos qos;
qos << dds::core::policy::EntityFactory::ManuallyEnable();
dds::domain::DomainParticipant::participant_factory_qos(qos);
//DomainParticipant participant(0, participant_qos);
//DDSDomainRepo::GetDomain(0)
GenericSubscriber subscriber(DDSDomainRepo::GetDomain(0), false);
//GenericSubscriber subscriber(participant, false);
GenericSubscriber::TTopics topics;
subscriber.list_topics(topics);
_info.clear();
for (auto& itr : topics) {
if (itr.second == "TypeInt") {
_info.push_back(std::make_tuple(itr.first,'i'));
}
if (itr.second == "TypeChar") {
_info.push_back(std::make_tuple(itr.first, 'c'));
}
if (itr.second == "TypeFloat") {
_info.push_back(std::make_tuple(itr.first, 'f'));
}
if (itr.second == "TypeShort") {
_info.push_back(std::make_tuple(itr.first, 's'));
}
if (itr.second == "TypeDouble") {
_info.push_back(std::make_tuple(itr.first, 'd'));
}
}
}
const DDSTopicInfo::TTypeVect& DDSTopicInfo::GetTopics() {
return DDSTopicInfo::Get()->_info;
}
DDSTopicInfo::DDSTopicInfo() {}
std::unique_ptr<CStatePriv> CStatePriv::_Ref;
CStatePriv & CStatePriv::Get() {
if (!_Ref) {
_Ref = std::make_unique<CStatePriv>();
}
return *_Ref.get();
}
void CStatePriv::Register(CStatePriv::TCBRef reg) {
_Cbs.push_back(reg);
}
void CStatePriv::Frame(int frameNum) {
for (auto cb : _Cbs) {
auto sp = cb.lock();
if (sp) {
sp->OnFrame(frameNum);
}
}
RemovedExpired<TCBVec, TCBWRef>(_Cbs);
}
int CStatePriv::GetFrame() {
return _frame;
}
int CStatePriv::GetState() {
_StateSub->Swap();
auto& buff = _StateSub->GetBuff();
if (buff.size() > 0)
return buff[0];
return -1;
}
CStatePriv::CStatePriv() {
_newFrameCb = make_shared<CStatePriv::OnNewFrame>(this);
_FrameSub = std::make_unique<DataStream<TypeInt>>("Frame", &DDSDomainRepo::GetDomain(0), _newFrameCb);
_StateSub = std::make_unique<TIntSubscription>("StateMode");
_StateSub->Register();
}
}
\ No newline at end of file
#pragma once
#ifndef NO_AUTOLINK_NADS_DDS_LIB
#define NO_AUTOLINK_NADS_DDS_LIB
#endif
#include <memory>
#include <string>
#include <dds/sub/ddssub.hpp>
#include <dds/core/ddscore.hpp>
#include <dds/dds.hpp>
#include <dds/pub/ddspub.hpp>
#include <rti/sub/SampleIterator.hpp>
#include <rti/util/util.hpp> // for sleep()
#include "NADS.hpp"
#include "ndds\dds_cpp\dds_cpp_domain.h"
#include "NadsDDSLib\NadsDDSLib.h"
#include "GenericSubscriber.h"
#include <thread>
#include <mutex>
namespace NADSDDS {
using namespace std;
using namespace dds::all;
template<class T> class CellPub : public CellRoot {
public:
CellPub(std::string name, dds::domain::DomainParticipant& dm, size_t size, int id) :
CellRoot(id), topic(dm, name)
{
writer = make_unique<dds::pub::DataWriter<T>>(dds::pub::Publisher(dm), topic);
data.data().resize(size);
data.eid() = _eid;
_itemCount = size;
_sizeInBytes = size * sizeof(T);
}
virtual void Send() override {
auto ptr = writer.get();
ptr->write(data);
}
virtual void* Raw() override {
return (void*)data.data().data();
}
virtual int& eid() override {
return data.eid();
}
unique_ptr< dds::pub::DataWriter<T> > writer;
dds::topic::Topic<T> topic;
T data;
};
//<singleton for holding domain participants
class DDSDomainRepo {
public:
static dds::domain::DomainParticipant& GetDomain(int id);
private:
typedef unique_ptr<DDSDomainRepo> TRef;
typedef unique_ptr<dds::domain::DomainParticipant> TDomainRef;
std::map<int, TDomainRef> _DomainRefs;
static TRef _self;
DDSDomainRepo();
};
class DDSTopicInfo {
public:
typedef std::tuple<std::string, char> TTypeInfo;
typedef std::vector<TTypeInfo> TTypeVect;
static void Refresh();
static const TTypeVect& GetTopics();
private:
DDSTopicInfo();
void RefreshImpl();
static DDSTopicInfo* Get();
TTypeVect _info;
typedef unique_ptr<DDSTopicInfo> TRef;
static TRef _self;
};
//class CFloatPub : public CellPub<TypeFloat> {};
class CFloatPub {
public:
typedef unique_ptr<CellPub<TypeFloat>> TRef;
CFloatPub(TRef &&in) :_ref(std::move(in)) {};
CFloatPub(CFloatPub &&in) :_ref(std::move(in._ref)) {}
TRef _ref;
CellPub<TypeFloat>* get() { return _ref.get(); }
CellPub<TypeFloat>* operator->() { return _ref.get(); }
};
class CDoublePub {
public:
typedef unique_ptr<CellPub<TypeDouble>> TRef;
CDoublePub(TRef &&in) :_ref(std::move(in)) {};
CDoublePub(CDoublePub &&in) :_ref(std::move(in._ref)) {}
TRef _ref;
CellPub<TypeDouble>* get() { return _ref.get(); }
CellPub<TypeDouble>* operator->() { return _ref.get(); }
};
class CCharPub {
public:
typedef unique_ptr<CellPub<TypeChar>> TRef;
CCharPub(TRef &&in) :_ref(std::move(in)) {};
CCharPub(CCharPub &&in) :_ref(std::move(in._ref)) {}
TRef _ref;
CellPub<TypeChar>* get() { return _ref.get(); }
CellPub<TypeChar>* operator->() { return _ref.get(); }
CellPub<TypeChar>& operator*() const { return *_ref.get(); }
CellPub<TypeChar>* operator()() { return _ref.get(); }
};
class CIntPub {
public:
typedef unique_ptr<CellPub<TypeInt>> TRef;
CIntPub(TRef &&in):_ref(std::move(in)) {};
CIntPub(CIntPub &&in ):_ref(std::move(in._ref)){}
TRef _ref;
CellPub<TypeInt>* get() { return _ref.get(); }
CellPub<TypeInt>* operator->() { return _ref.get(); }
};
class CShortPub {
public:
typedef unique_ptr<CellPub<TypeShort>> TRef;
CShortPub(TRef &&in) :_ref(std::move(in)) {};
CShortPub(CShortPub &&in) :_ref(std::move(in._ref)) {}
operator CellPub<TypeShort>* () { return _ref.get(); }
CellPub<TypeShort>* operator()() { return _ref.get(); }
TRef _ref;
CellPub<TypeShort>* get() { return _ref.get(); }
CellPub<TypeShort>* operator->() { return _ref.get(); }
};
template < class T> class OnNewData {
public:
OnNewData() {};
virtual void NewData(const T&) = 0;
};
typedef std::shared_ptr<OnNewData<TypeInt>> TIntCB;
typedef std::shared_ptr<OnNewData<TypeChar>> TCharCB;
typedef std::shared_ptr<OnNewData<TypeShort>> TShortCB;
typedef std::shared_ptr<OnNewData<TypeFloat>> TFloatCB;
typedef std::shared_ptr<OnNewData<TypeDouble>> TDoubleCB;
template < class T> class DataListener : public dds::sub::NoOpDataReaderListener<T> {
public:
typedef std::shared_ptr<OnNewData<T>> TCbRef;
DataListener(TCbRef ref) :_cb(ref) {};
void on_data_available(dds::sub::DataReader<T>& reader) {
dds::sub::LoanedSamples<T> samples = reader.take();
rti::sub::SampleIterator<T> it;// = dds::sub::LoanedSamples<T>::iterator
for (rti::sub::SampleIterator<T> sample_it = samples.begin(); sample_it != samples.end(); sample_it++) {
if (sample_it->info().valid()) {
_sample = sample_it->data();
_hasData = true;
}
}
if (_cb)
_cb->NewData(_sample);
}
bool HasData() { return _hasData; }
const T& GetCurrVal() { return _sample; }
private:
T _sample;
bool _hasData;
TCbRef _cb;
};
class StreamBase {
public:
StreamBase(dds::domain::DomainParticipant* dom, const std::string& topicName) :_dom(dom), _topicName(topicName) {};
protected:
dds::domain::DomainParticipant* _dom;
std::string _topicName;
};
template <class T> class DataStream : public StreamBase {
public:
typedef std::shared_ptr<OnNewData<T>> TCbRef;
DataStream(const std::string &topicName, dds::domain::DomainParticipant* dom, TCbRef ref) :StreamBase(dom, topicName), _listener(ref)
{
_topic = new dds::topic::Topic<T>(*_dom, topicName);
_reader = new dds::sub::DataReader<T>(
dds::sub::Subscriber(*_dom),
*_topic,
dds::core::QosProvider::Default().datareader_qos(),
&_listener,
dds::core::status::StatusMask::data_available());
}
~DataStream() {};
private:
std::string _subject;
dds::sub::DataReader<T>* _reader;
dds::topic::Topic<T>* _topic;
DataListener<T> _listener;
};
//BufferedCellRoot: public CellRoot{
// public:
// BufferedCellRoot(int id) : CellRoot(id) {}
template <class T, class Y> class CellSubsScription : public BufferedCellRoot<T>{
public:
class CB : public OnNewData<Y> {
public:
CB():OnNewData<Y>(),_hasNewData(false){}
virtual void NewData(const Y& valIn) override {
lock_guard<std::mutex> lock(_mutex);
_buffer = valIn;
_hasNewData = true;
}
void GetData(std::vector<T>& valIn) {
lock_guard<std::mutex> lock(_mutex);
size_t bufferSize = _buffer.data().size();
if (valIn.size() != bufferSize){
valIn.resize(bufferSize);
}
for (size_t i = 0; i < bufferSize; i++) {
valIn[i] = _buffer.data()[i];
}
_hasNewData = false;
}
bool HasNewData() {
return _hasNewData;
}
std::string _name;
protected:
volatile bool _hasNewData;
std::mutex _mutex;
Y _buffer;
};
typedef
CellSubsScription(const std::string& name) :BufferedCellRoot<T>(name) {}
void Register(){
_cb = make_shared<CB>();
_cb->_name = BufferedCellRoot<T>::_name;
_dataStream = make_unique<DataStream<Y>>(BufferedCellRoot<T>::_name, &DDSDomainRepo::GetDomain(0), _cb);
}
virtual bool Swap() override {
if (_cb && _cb->HasNewData()) {
_cb->GetData(BufferedCellRoot<T>::_buffer);
BufferedCellRoot<T>::_sizeInBytes = sizeof(T) * BufferedCellRoot<T>::_buffer.size();
return true;
}
return false;
}
virtual int eid() override {
return _streamBuffer.eid();
}
protected:
Y _streamBuffer;
unique_ptr<DataStream<Y>> _dataStream;
shared_ptr<CB> _cb;
};
typedef CellSubsScription<float, TypeFloat> TFloatSubscription;
typedef CellSubsScription<double,TypeDouble> TDoubleSubscription;
typedef CellSubsScription<int, TypeInt> TIntSubscription;
typedef CellSubsScription<short, TypeShort> TShortSubscription;
typedef CellSubsScription<char, TypeChar> TCharSubscription;
typedef std::unique_ptr<TFloatSubscription> TFloatSubscriptionRef;
typedef std::unique_ptr<TDoubleSubscription>TDoubleSubscriptionRef;
typedef std::unique_ptr<TIntSubscription> TIntSubscriptionRef;
typedef std::unique_ptr<TShortSubscription> TShortSubscriptionRef;
typedef std::unique_ptr<TCharSubscription> TCharSubscriptionRef;
/////////////////////////////////////////////////////////
///\brief
/// remove expired weak pointers from vector
///\remark
/// use:
/// typedef weak_ptr<MyClass> TWeak
/// typedef vector<TWeak> TVecs;
/// TVecs vector;
/// RemovedExpired<TVecs,TWeak>(vector);
////////////////////////////////////////////////////////
template<class TVec, class TWp>
void RemovedExpired(TVec &vec) {
vec.erase(
std::remove_if(
vec.begin(),
vec.end(),
[](TWp cb) {return cb.expired(); }),
vec.end());
}
class CStatePriv {
public:
static CStatePriv & Get();
class Callback {
public:
Callback() {};
virtual void OnFrame(int num) = 0;
};
typedef std::shared_ptr<Callback> TCBRef;
typedef std::weak_ptr<Callback> TCBWRef;
CStatePriv();
int GetFrame();
int GetState();
void Register(TCBRef);
protected:
static std::unique_ptr<CStatePriv> _Ref;
void Frame(int frameNumber);
class OnNewFrame : public OnNewData<TypeInt> {
public:
OnNewFrame(CStatePriv* par):_par(par){}
virtual void NewData(const TypeInt& val) override {
_par->Frame(val.data()[0]);
}
CStatePriv* _par;
};
std::unique_ptr<DataStream<TypeInt>> _FrameSub;
TIntSubscriptionRef _StateSub;
typedef std::vector<TCBWRef> TCBVec;
std::shared_ptr<OnNewFrame> _newFrameCb;
TCBVec _Cbs;
int _frame;
};
}
#include "stdafx.h"
#include <NadsDDSLib\NadsDDSLib.h>
#include <nadsddsimpl.h>
namespace NADSDDS {
CPublication::TRef
CPublication::MakePublication(const std::string& name, int EID, size_t count, char cellType) {
CPublication::TRef ret;
switch (cellType)
{
case 'c':{
unique_ptr<CCharPub> ptr = make_unique<CCharPub>(CCharPub::TRef(new CellPub<TypeChar>(name, DDSDomainRepo::GetDomain(0), count, EID)));
return make_unique<CharPublication>(unique_ptr< CCharPub>(std::move(ptr)));
};
case 'f': {
unique_ptr<CFloatPub> ptr = make_unique<CFloatPub>(CFloatPub::TRef(new CellPub<TypeFloat>(name, DDSDomainRepo::GetDomain(0), count, EID)));
return make_unique<FloatPublication>(unique_ptr<CFloatPub>(std::move(ptr)));
};
case 'd': {
unique_ptr<CDoublePub> ptr = make_unique<CDoublePub>(make_unique<CellPub<TypeDouble>>(name, DDSDomainRepo::GetDomain(0), count, EID));
return make_unique<DoublePublication>(unique_ptr<CDoublePub>(std::move(ptr)));
};
case 's': {
unique_ptr<CShortPub> ptr = make_unique<CShortPub>(make_unique<CellPub<TypeShort>>(name, DDSDomainRepo::GetDomain(0), count, EID));
return make_unique<ShortPublication>(unique_ptr<CShortPub>(std::move(ptr)));
};
case 'i': {
unique_ptr<CIntPub> ptr = make_unique<CIntPub>(make_unique<CellPub<TypeInt>>(name, DDSDomainRepo::GetDomain(0), count, EID));
return make_unique<IntPublication>(unique_ptr<CIntPub>(std::move(ptr)));
};
default:
return ret;
break;
}
}
char* CPublication::asChar() { return nullptr; };
double* CPublication::asDouble() { return nullptr; };
float* CPublication::asFloat() { return nullptr; };
int* CPublication::asInt() { return nullptr; };
short* CPublication::asShort() { return nullptr; };
const std::string& CPublication::Name() { return GetPub()->_name;};
int CPublication::EID() {
return GetPub()->eid();
}
void* CPublication::Raw() {
auto ptr = GetPub();
return ptr->Raw();
}
size_t CPublication::SizeInBytes() {
return GetPub()->_sizeInBytes;
}
size_t CPublication::Count() {
return GetPub()->_itemCount;
}
DoublePublication::DoublePublication(TDoublePubPtr&& ptr) :_ref(std::move(ptr)) {}
double* DoublePublication::asDouble() {
return (double*)_ref->get()->Raw();
}
void DoublePublication::Publish() {
(_ref)->get()->Send();
}
DoublePublication& DoublePublication::operator= (double val) {
TypeDouble &dval = _ref->get()->data;
dval.data()[0] = val;
return *this;
}
double& DoublePublication::operator[] (size_t index) {
static double nothing=0;
TypeDouble &dval = _ref->get()->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* DoublePublication::GetPub() {
return _ref->get();
}
FloatPublication::FloatPublication(TFloatPubPtr&& ptr) :_ref(std::move(ptr)) {}
float* FloatPublication::asFloat() {
return (float*)_ref->get()->Raw();
}
FloatPublication& FloatPublication::operator= (float val) {
auto &dval = _ref->get()->data;
dval.data()[0] = val;
return *this;
}
float& FloatPublication::operator[] (size_t index) {
static float nothing = 0;
auto &dval = _ref->get()->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* FloatPublication::GetPub() {
return _ref->get();
}
void FloatPublication::Publish() {
(_ref)->get()->Send();
}
ShortPublication::ShortPublication(TShortPubPtr&& ptr) :_ref(std::move(ptr)) {}
short* ShortPublication::asShort() {
return (short*)_ref->get()->Raw();
}
ShortPublication& ShortPublication::operator= (short val) {
auto &dval = _ref->get()->data;
dval.data()[0] = val;
return *this;
}
short& ShortPublication::operator[] (size_t index) {
static short nothing = 0;
auto &dval = _ref->get()->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* ShortPublication::GetPub() {
return (CellPub<TypeShort>*)_ref.get();
}
void ShortPublication::Publish() {
(_ref)->get()->Send();
}
IntPublication::IntPublication(TIntPubPtr&& ptr) :_ref(std::move(ptr)) {}
int* IntPublication::asInt() {
return (int*)_ref->get()->Raw();
}
IntPublication& IntPublication::operator= (int val) {
auto &dval = _ref->get()->data;
dval.data()[0] = val;
return *this;
}
int& IntPublication::operator[] (size_t index) {
static int nothing = 0;
auto &dval = _ref->get()->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* IntPublication::GetPub() {
return _ref->get();
}
void IntPublication::Publish() {
(_ref)->get()->Send();
}
CharPublication::CharPublication(TCharPubPtr&& ptr) :_ref(std::move(ptr)) {}
char* CharPublication::asChar() {
return (char*)_ref->_ref->Raw();
}
CharPublication& CharPublication::operator= (const std::string& str) {
auto &dval = _ref->get()->data;
dval.data() = str;
return *this;
}
char& CharPublication::operator[] (size_t index) {
static char nothing = 0;
auto &dval = _ref->_ref->data;
if (dval.data().size() > index) {
return dval.data()[index];
}
return nothing;
}
CellRoot* CharPublication::GetPub() {
return _ref->_ref.get();
}
void CharPublication::Publish() {
(_ref)->get()->Send();
}
size_t CSubscription::GetSizeInByes() {
return GetCell()->_sizeInBytes;
}
void* CSubscription::GetRaw() {
return GetCell()->Raw();
}
CSubscription::TRef
CSubscription::MakeSubscription(const std::string& name, char cellType) {
CSubscription::TRef ret;
switch (cellType)
{
case 'c': {
TCharSubscriptionRef ptr = make_unique<TCharSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CCharSubscription(std::move(ptr)));
};
case 'f': {
TFloatSubscriptionRef ptr = make_unique<TFloatSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CFloatSubscription(std::move(ptr)));
};
case 'd': {
TDoubleSubscriptionRef ptr = make_unique<TDoubleSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CDoubleSubscription(std::move(ptr)));
};
case 's': {
TShortSubscriptionRef ptr = make_unique<TShortSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CShortSubscription(std::move(ptr)));
};
case 'i': {
TIntSubscriptionRef ptr = make_unique<TIntSubscription>(name);
ptr->Register();
return CSubscription::TRef(new CIntSubscription(std::move(ptr)));
};
default:
return ret;
break;
}
}
class CBPriv : public CStatePriv::Callback {
public:
CBPriv(CState* par) :_par(par) {};
CState* _par;
void OnFrame(int num) {
_par->NewFrame(num);
}
~CBPriv() {};
};
void CState::NewFrame(int frame) {
for (auto cb : _Cbs) {
auto sp = cb.lock();
if (sp) {
sp->OnFrame(frame);
}
}
RemovedExpired<TCBWRefs, TCBWRef>(_Cbs);
}
int CState::GetFrame() {
return CStatePriv::Get().GetFrame();
}
int CState::GetState() {
return CStatePriv::Get().GetState();
}
void CState::Register(TCBRef ref) {
_Cbs.push_back(ref);
if (!_privCB) {
_privCB = make_shared<CBPriv>(this);
CStatePriv::Get().Register(_privCB);
}
}
CState::CState() {
}
CState::~CState() {
}
namespace Info {
void GetCellInfo(TCellInfoVec& cells) {
DDSTopicInfo::Refresh();
cells = DDSTopicInfo::GetTopics();
}
}
}
\ No newline at end of file
/*
/ (c) Copyright 2018, Real-Time Innovations, All rights reserved. /
/ /
/ RTI grants Licensee a license to use, modify, compile, and create /
/ derivative works of the software solely for use with RTI Connext DDS. /
/ Licensee may redistribute copies of the software provided that all such /
/ copies are subject to this license. The software is provided "as is", with /
/ no warranty of any type, including any warranty for fitness for any purpose. /
/ RTI is under no obligation to maintain or support the software. RTI shall /
/ not be liable for any incidental or consequential damages arising out of the /
/ use or inability to use the software. /
*/
#include "transform_xml.h"
#include <fstream>
#include <sstream>
#include <algorithm>
#include <xml/parser>
#include <xml/serializer>
using namespace xml;
struct MatchPathSeparator
{
bool operator()( char ch ) const
{
return ch == '\\' || ch == '/';
}
};
static std::string basename(std::string const& pathname )
{
return std::string(std::find_if(pathname.rbegin(), pathname.rend(), MatchPathSeparator()).base(),
pathname.end() );
}
std::string transform_xml(std::string& filename)
{
bool transforming=false;
int depth=0;
std::ifstream ifs;
ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit);
ifs.open (filename, std::ifstream::in | std::ifstream::binary);
// Configure the parser to receive attributes as events as well
// as to receive prefix-namespace mappings (namespace declarations
// in XML terminology).
//
parser p(ifs,
filename,
parser::receive_default |
parser::receive_attributes_event |
parser::receive_namespace_decls);
std::stringstream type_definition;
serializer s(type_definition, "typedef", 1);
s.xml_decl();
for (parser::event_type e (p.next ()); e != parser::eof; e = p.next ())
{
switch (e)
{
case parser::start_element:
{
if(p.qname().string() == "type_library") {
return filename;
}
if(p.qname().string() == "types") {
qname transformed_qname("dds");
s.start_element(transformed_qname);
s.namespace_decl("http://www.w3.org/2001/XMLSchema-instance", "xsi");
transforming=true;
} else {
s.start_element(p.qname());
if(transforming) {
++depth;
}
}
break;
}
case parser::end_element:
{
if(transforming && depth == 0) {
s.end_element();
transforming=false;
} else if(transforming) {
depth=std::max(0,--depth);
}
s.end_element();
break;
}
case parser::start_namespace_decl:
{
break;
}
case parser::end_namespace_decl:
{
// There is nothing in XML that indicates the end of namespace
// declaration since it is scope-based.
//
break;
}
case parser::start_attribute:
{
s.start_attribute(p.qname());
break;
}
case parser::end_attribute:
{
s.end_attribute();
if(transforming && depth == 0) {
s.start_element("type_library");
s.start_attribute("name");
s.characters("MyTypes");
s.end_attribute();
depth=1;
}
break;
}
case parser::characters:
{
s.characters(p.value());
break;
}
}
}
s.end_element();
std::string fullpath = "/tmp/" + basename(filename);
std::ofstream file(fullpath);
file << type_definition.str();
file.close();
return fullpath;
}
/********************************************************************************/
/* (c) Copyright 2018, Real-Time Innovations, All rights reserved. */
/* */
/* RTI grants Licensee a license to use, modify, compile, and create */
/* derivative works of the software solely for use with RTI Connext DDS. */
/* Licensee may redistribute copies of the software provided that all such */
/* copies are subject to this license. The software is provided "as is", with */
/* no warranty of any type, including any warranty for fitness for any purpose. */
/* RTI is under no obligation to maintain or support the software. RTI shall */
/* not be liable for any incidental or consequential damages arising out of the */
/* use or inability to use the software. */
/********************************************************************************/
#ifndef _TRANSFORM_XML_H_INCLUDED
#define _TRANSFORM_XML_H_INCLUDED
#include <string>
/**
* @brief transform an XML representation of a datatype as emitted by
* "rtiddsgen -convertToXml" to an XML format compatible with the modern C++
* QosProvider constructor argument
*
* @param filename full path to the file containing an rtiddsgen XML datatype representation
* @return std::string full path to a converted file suitable for passing to QosProvider
* constructor
*/
std::string transform_xml(std::string& filename);
#endif
/*
/ (c) Copyright 2018, Real-Time Innovations, All rights reserved. /
/ /
/ RTI grants Licensee a license to use, modify, compile, and create /
/ derivative works of the software solely for use with RTI Connext DDS. /
/ Licensee may redistribute copies of the software provided that all such /
/ copies are subject to this license. The software is provided "as is", with /
/ no warranty of any type, including any warranty for fitness for any purpose. /
/ RTI is under no obligation to maintain or support the software. RTI shall /
/ not be liable for any incidental or consequential damages arising out of the /
/ use or inability to use the software. /
*/
#include "value_as_string.h"
#include <sstream>
#include <string>
using namespace dds::core;
static std::string do_text_conversion(const rti::core::xtypes::DynamicDataMemberInfo& info,
uint32_t member_index,
const xtypes::DynamicData& data,
bool add_name);
static std::string decode_sequence(const xtypes::DynamicData& data)
{
std::stringstream buffer;
int num_members = data.member_count();
for(int32_t i = 1; i <= num_members; ++i) {
buffer << " " << do_text_conversion(data.member_info(i), i, data, true);
}
return buffer.str();
}
static std::string do_text_conversion(const rti::core::xtypes::DynamicDataMemberInfo& info,
uint32_t member_index,
const xtypes::DynamicData& data,
bool add_name)
{
std::stringstream buffer;
std::string name=(add_name && (info.member_name().c_str() != nullptr))?(info.member_name().to_std_string()+"="):"";
switch(info.member_kind().underlying()) {
case xtypes::TypeKind_def::BOOLEAN_TYPE:
buffer << name << data.value<bool>(member_index);
return buffer.str();
case xtypes::TypeKind_def::UINT_8_TYPE:
buffer << name << static_cast<uint32_t>(data.value<uint8_t>(member_index));
return buffer.str();
case xtypes::TypeKind_def::INT_16_TYPE:
buffer << name << data.value<int16_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::UINT_16_TYPE:
buffer << name << data.value<uint16_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::INT_32_TYPE:
buffer << name << data.value<int32_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::UINT_32_TYPE:
buffer << name << data.value<uint32_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::INT_64_TYPE:
buffer << name << data.value<int64_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::UINT_64_TYPE:
buffer << name << data.value<uint64_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::FLOAT_32_TYPE:
buffer << name << data.value<float>(member_index);
return buffer.str();
case xtypes::TypeKind_def::FLOAT_64_TYPE:
buffer << name << data.value<double>(member_index);
return buffer.str();
case xtypes::TypeKind_def::FLOAT_128_TYPE:
buffer << name << "Unsupported Floating point type";
return buffer.str();
case xtypes::TypeKind_def::CHAR_8_TYPE:
buffer << name << data.value<char>(member_index);
return buffer.str();
case xtypes::TypeKind_def::ENUMERATION_TYPE:
buffer << name << data.value<uint32_t>(member_index);
return buffer.str();
case xtypes::TypeKind_def::STRING_TYPE:
buffer << name << data.value<std::string>(member_index);
return buffer.str();
case xtypes::TypeKind_def::WSTRING_TYPE:
return std::string();
case xtypes::TypeKind_def::ARRAY_TYPE:
return std::string();
case xtypes::TypeKind_def::UNION_TYPE:
case xtypes::TypeKind_def::STRUCTURE_TYPE:
case xtypes::TypeKind_def::SEQUENCE_TYPE:
return decode_sequence(data.value<xtypes::DynamicData>(member_index));
default:
return std::string();
}
}
// represent given dynamic data value as a string
std::string value_as_string(const xtypes::DynamicData& data, const std::string& member_name)
{
return do_text_conversion(data.member_info(member_name),
data.member_info(member_name).member_index(),
data,
false);
}
/********************************************************************************/
/* (c) Copyright 2018, Real-Time Innovations, All rights reserved. */
/* */
/* RTI grants Licensee a license to use, modify, compile, and create */
/* derivative works of the software solely for use with RTI Connext DDS. */
/* Licensee may redistribute copies of the software provided that all such */
/* copies are subject to this license. The software is provided "as is", with */
/* no warranty of any type, including any warranty for fitness for any purpose. */
/* RTI is under no obligation to maintain or support the software. RTI shall */
/* not be liable for any incidental or consequential damages arising out of the */
/* use or inability to use the software. */
/********************************************************************************/
#ifndef _VALUE_AS_STRING_H_
#define _VALUE_AS_STRING_H_
#include <dds/dds.hpp>
#include <string>
/**
* @brief for a given member of a dynamic datatype return a std::string
* representation of its value
*
* @param data dynamic datatype to which the member belongs
* @param member_name name of the member
* @return std::string string representation of members value
*/
std::string value_as_string(const dds::core::xtypes::DynamicData& data,
const std::string& member_name);
#endif
\ No newline at end of file
File added
File added
File added
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment