I wonder if I understood emplace_back correctly
#include <vector>
using namespace std;
struct Hero {
Hero(const string&) {}
Hero(const char*) {}
Hero(int) {}
// forbid a clone:
Hero(const Hero&) = delete;
Hero& operator=(const Hero&) = delete;
};
int main() {
vector<Hero> heros1 = { "Bond", "Hulk", "Tarzan" }; // ERR: copies?
vector<Hero> heros;
heros.emplace_back( 5 ); // ERR: copies
heros.emplace_back( string("Bond") ); // ERR: copies
heros.emplace_back( "Hulk" ); // ERR: copies
}
Thus, I am really wondering If I understood emplace_back incorrectly: I though it would prevent to make a copy of Hero, because it creates the Item in-place.
Or is it a implementation error in my g++-4.7.0?
You need to define a move constructor and move-assignment operator, like this:
struct Hero {
Hero(const string&) {}
Hero(const char*) {}
Hero(int) {}
Hero(Hero&&) {}
Hero& operator=(Hero&&) { return *this; }
// forbid a clone:
Hero(const Hero&) = delete;
Hero& operator=(const Hero&) = delete;
};
This allows values of type Hero to be moved into the function. Move is usually faster than copy. If the type is neither copyable nor movable then you cannot use it in a std::vector.
It's no implementation error- you did not provide a move constructor.
Uh... I got it.
If I forbit to copy the Heros, I must allow them to move, if I want to put them in containers. How silly of me.
struct Hero {
Hero(const string&) {}
Hero(const char*) {}
Hero(int) {}
// no clone:
Hero(const Hero&) = delete;
Hero& operator=(const Hero&) = delete;
// move only:
Hero(Hero&&) {}
Hero& operator=(Hero&&) {}
};
And all examples except for the initializer list work.
Related
I wanted to hook some functions from instagram apk using frida, decompiled the apk with
jadx/JEB, one of the functions I wanted to hook was in this:
public static void A00(HGf arg8, I1Y arg9) {
arg8.A0P();
Boolean v0 = arg9.A0v;
if(v0 != null) {
arg8.A0l("about_your_account_bloks_entrypoint_enabled", v0.booleanValue());
}
//some other code here
}
Tried to hook the function with this frida script:
try {
//
let I1X = Java.use("X.I1X")
console.log("this is instance: ", I1X)
console.log(
"these are the methods:: ",
Java.use("X.I1X").class.getDeclaredMethods()
)
I1X.A00.overload().implemention = function (HGf, I1Y) {
console.log("A0l is called")
let ret = this.A0l(str, z)
console.log("A0l ret value is " + ret)
}
} catch (e) {
console.log("failed!" + e)
}
})
this script outputs:
this is instance: <class: X.I1X>
these are the methods::
failed!TypeError: not a function
apparently the A00 here is not a function, so back to jadx in the compiled code there is another class with the same name within same package but consisting of some other code, here it is:
/* renamed from: X.I1x reason: case insensitive filesystem */
/* loaded from: classes7.dex */
public final class C39227I1x {
public C39229I1z A00 = null;
}
apparently Frida is hooking this variable instance A00 In my opinion that is why
it is returning not a function here.
So my question, how can I hook like this situation?
Edit:
the two classes are somewhat different in jadx.
My environment:
RadStudio 10.2 Tokyo
Working on Windows 10 (64bit) v1809
I was searching the way to replace JSON value.
Then, I came across the following Q and A.
Delphi XE7: How to change a JSON value using System.JSON (versus SuperObject)
In Delphi:
JoPair.JsonValue.Free;
JoPair.JsonValue := TJSONNumber.Create(123);
Following this, I thought, it would be in C++ Builder
JoPair->JsonValue->Free();
JoPair->JsonValue = new TJSONNumber(123);
However, it caused "access violation" error in ToString();
Instead, I commented out JoPair->JsonValue->Free();, then no problem.
Question:
In C++ Buidler, should I need Free JoPair->JsonValue?
But without Freeing the JsonValue, it may cause memory leak.
source code
Following is the actual code I checked
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <DBXJSON.hpp> // for JSON
#include <memory> // for unique_ptr
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String srcFileName = L"test.json"; // source
String dstFileName = L"out.json"; // destination
String targetKeySubString = L"hogehoge"; //
String targetValue = "9";
// 1. read JSON strings
std::unique_ptr<TStringList> slread(new TStringList);
slread->LoadFromFile(srcFileName);
// 2. replace values for the key (target is checked by substring)
TJSONObject *jsonObj;
String jsonKey, jsonValue;
TJSONPair *pairObj;
std::unique_ptr<TStringList> slwrite(new TStringList);
for(int li=0; li < slread->Count; li++) { // file line index
String jsonText = slread->Strings[li];
// this is needed for avoiding error caused by the file path treating backslash
jsonText = StringReplace(jsonText, L"\\", L"\\\\", TReplaceFlags()<<rfReplaceAll);
//
jsonObj = dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(jsonText));
for(int pi=0; pi < jsonObj->Size(); pi++) { // pair index
pairObj = jsonObj->Get(pi);
jsonKey = pairObj->JsonString->Value();
jsonValue = pairObj->JsonValue->Value();
if (jsonKey.Pos(targetKeySubString) == 0) {
continue;
}
// replace value
// (ref: https://stackoverflow.com/questions/33426576/delphi-xe7-how-to-change-a-json-value-using-system-json-versus-superobject)
//
//pairObj->JsonValue->Free(); // commented out because this causes "access violation" in ToString()
pairObj->JsonValue = new TJSONString(targetValue);
// debug
//ShowMessage(jsonKey + ":" + jsonValue);
}
slwrite->Add(jsonObj->ToString());
}
jsonObj->Free();
// 3. output
slwrite->SaveToFile(dstFileName);
ShowMessage(L"Done");
}
//---------------------------------------------------------------------------
Example
{"1_hogehoge":"3", "2_fugafuga":"1","3_hogehoge":"4", "4_fugafuga":"1", "5_hogehoge":"5", "6_fugafuga":"9"}
{"1_hogehoge":"9","2_fugafuga":"1","3_hogehoge":"9","4_fugafuga":"1","5_hogehoge":"9","6_fugafuga":"9"}
Source code (10.2 Tokyo)
I have updated the source code. Still same problem.
I also used ToJSON() instead of ToString() with same error (access violation)`.
I also tried using std::unique_ptr, which caused another error. So I gave up using std::unique_ptr on this topic now (may better be investigated separately).
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <System.JSON.hpp>
#include <memory> // for unique_ptr
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String srcFileName = L"test.json"; // source
String dstFileName = L"out.json"; // destination
String targetKeySubString = L"hogehoge"; //
String targetValue = "9";
// 1. read JSON strings
std::unique_ptr<TStringList> slread(new TStringList);
slread->LoadFromFile(srcFileName);
// 2. replace values for the key (target is checked by substring)
TJSONObject *jsonObj;
//std::unique_ptr<TJSONObject> jsonObj(new TJSONObject);
String jsonKey, jsonValue;
TJSONPair *pairObj;
std::unique_ptr<TStringList> slwrite(new TStringList);
for(int li=0; li < slread->Count; li++) { // file line index
String jsonText = slread->Strings[li];
// this is needed for avoiding error caused by the file path treating backslash
jsonText = StringReplace(jsonText, L"\\", L"\\\\", TReplaceFlags()<<rfReplaceAll);
//
jsonObj = dynamic_cast<TJSONObject*>(TJSONObject::ParseJSONValue(jsonText));
if (jsonObj == NULL) {
continue;
}
for(int pi=0; pi < jsonObj->Count; pi++) { // pair index
pairObj = jsonObj->Pairs[pi];
jsonKey = pairObj->JsonString->Value();
jsonValue = pairObj->JsonValue->Value();
if (jsonKey.Pos(targetKeySubString) == 0) {
continue;
}
// replace value
// (ref: https://stackoverflow.com/questions/33426576/delphi-xe7-how-to-change-a-json-value-using-system-json-versus-superobject)
//
//pairObj->JsonValue->Free(); // commented out because this causes "access violation" in ToString()
delete pairObj->JsonValue;
pairObj->JsonValue = new TJSONString(targetValue);
// debug
//ShowMessage(jsonKey + ":" + jsonValue);
}
//String res = jsonObj->ToJSON(); // *** access violation ***
String res = jsonObj->ToString(); // *** access violation ***
slwrite->Add(res);
jsonObj->Free();
}
// 3. output
slwrite->SaveToFile(dstFileName);
ShowMessage(L"Done");
}
//---------------------------------------------------------------------------
I want to use the following template member function
template <typename Entity>
class SomeCollection
{
// ....
template <typename Measure, typename Filter>
Entity maximalEntity(Measure&& measure, Filter&& requirement)
{
auto maxEntity = Entity();
auto maxValue = -std::numeric_limits<double>::infinity();
for (auto ent /* some iteration method*/)
{
auto measurement = measure(ent);
if (requirement(ent) && measurement > maxValue)
std::tie(maxEntity, maxValue) = std::make_tuple { ent, measurement };
}
return maxEntity;
}
// ...
};
What is the best way to call this function from client code without Filter requirement (to just have the maximal element) ?
The best I can come up with is:
class Something;
double measure(Something&);
SomeCollection<Something> collection;
auto maximum = collection.maximalEntity(measure, [](const Something&) { return true; });
But I guess this lambda function could be improved no ?
Not sure how the lambda can be improved, but you could define a generic lambda that given any input would return always true (which could also be used here):
auto always_true = [](auto&&...) { return true; };
and you would use it as:
auto maximum = collection.maximalEntity(measure, always_true);
Live demo
An equivalent implementation for C++11 is the following:
struct always_true {
template<typename... Args>
bool operator()(Args&&...) const noexcept {
return true;
}
};
which would then be used as:
auto maximum = collection.maximalEntity(measure, always_true{});
Live demo
You could create a lambda which returns true and set it as default parameter.
auto true_filter = [](const Something& arg){ return true; };
//auto true_filter = [](auto&& arg){ return true; }; if you have c++14
...
template <typename Measure, typename Filter = decltype(true_filter)>
Entity maximalEntity(Measure&& measure, Filter requirement = true_filter)
{
...
auto maximum = collection.maximalEntity(measure);
Note the Filter has changed from Filter&&. I have not get it to work with rvalue refs here.
Though having it explicitly stated is probably better design. Just an option to have it "shorter"
C++14:
template<class T>
auto always() {
return [](auto&&...)->T{return {};};
};
or in C++11:
template<class T>
struct always {
template<class...Args>
T operator()(Args&&...)const{ return {}; }
};
use:
collection.maximalEntity(measure, always<std::true_type>());
this has the advantage that the truth of the lambda involved is encoded in the type system, which makes it marginally easier for compilers to optimize its behavior.
This also lets you do always<std::false_type> or always<std::integral_constant<int, 42>>() etc.
In C++17 I'd do:
template<auto x>
auto always() {
return [](auto&&)->std::integral_constant<decltype(x), x>
{ return {}; };
}
which permits always<true>() and always<42>() (and maybe always<nullptr>()?).
I'm writing a shader in CG language for Unity3d.
If you make a shader for transparent object you need to create two similar passes in SubShader. The first one to render only back faces (with Cull Front) and the second one to render only front faces (with Cull Back). But the code for vertex and fragment function is the same for two passes.
Is it possible not to double a code and declare some functions, that would be shared between passes?
I want to have something like in my code example:
Shader "cool shader" {
Properties {
...
}
SubShader {
CGPROGRAM
// need to declare vertexOutput somewhow here
float4 sharedFragFoo(vertexOutput i) : COLOR // How to make smth like this?
{
....
return float4(...);
}
ENDCG
pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
vertexOutput vert(vertexInput v) {
vertexOutput o;
...
return o;
}
float4 frag(vertexOutput i) : COLOR
{
return sharedFragFoo(i); // call the shared between passes function
}
ENDCG
}
pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
vertexOutput vert(vertexInput v) {
vertexOutput o;
...
return o;
}
float4 frag(vertexOutput i) : COLOR
{
return sharedFragFoo(i); // call the shared between passes function
}
ENDCG
}
}
}
UPD: Found out how to do it using includes.
But is it possible to do inside one file?
You can do it in one file using CGINCLUDE. If you look at the shader for MobileBlur ("Hidden/FastBlur") by Unity it has shared code at the top and passes below.
Here are just the key parts - note CGINCLUDE/ENDCG outside of the SubShader/Pass
Shader "YourShader"
{
...
CGINCLUDE
#include "UnityCG.cginc"
struct shared_v2f
{
float4 pos : SV_POSITION;
}
shared_v2f myVert( appdate_img v )
{
shared_v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
return o;
}
fixed4 myFrag( shared_v2f i ) : SV_Target
{
return fixed4( 1.0, 0.5, 0.0, 1.0 );
}
ENDCG
SubShader
{
...
Pass
{
CGPROGRAM
#pragma vertex myVert
#pragma fragment myFrag
ENDCG
}
}
}
Answering my own question. Wierdo!
Hope it will help somebody else.
You can write all that betwee CGPROGRAM and ENDCG in separate *.cginc file and include it inside each pass.
Important! But you need to write
#pragma vertex vert and #pragma fragment frag inside your main shader file, otherwise it will compile but won't work. I suppose that the reason is that pragma'ss are processed before include's.
Here is my code sample.
Main shader definition file:
Shader "cool shader" {
Properties {
// properties
}
SubShader {
...
pass {
Cull Front
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "shared.cginc"
ENDCG
}
pass {
Cull Back
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "shared.cginc"
ENDCG
}
}
}
Shared file shared.cginc:
#ifndef SHARED_FOO
#define SHARED_FOO
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform float4 _Color;
// other variables....
struct vertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;
float4 posWorld : TEXCOORD1;
float4 posInObjectCoords : TEXCOORD2;
float3 normalDir : TEXCOORD3;
};
vertexOutput vert(vertexInput v) {
vertexOutput o;
// do staff
return o;
}
float4 frag(vertexOutput i) : COLOR
{
// do staff
return float4(...);
}
#endif // SHARED_FOO
In StringTemplate - which I've used in some projects to emit C code - whitespace prefixes are automatically added in the output lines:
PrintCFunction(linesGlobal, linesLocal) ::= <<
void foo() {
if (someRuntimeFlag) {
<linesGlobal>
if (anotherRuntimeFlag) {
<linesLocal>
}
}
}
>>
When this template is rendered in StringTemplate, the whitespace
prefixing the multilined linesGlobal and linesLocal strings,
is copied for all the lines emitted. The generated C code is
e.g.:
void foo() {
if (someRuntimeFlag) {
int i;
i=1; // <=== whitespace prefix copied in 2nd
i++; // <=== and 3rd line
if (anotherRuntimeFlag) {
int j=i;
j++; // <=== ditto
}
}
}
I am new to Jinja2 - and tried to replicate this, to see if I can use Python/Jinja2 to do the same thing:
#!/usr/bin/env python
from jinja2 import Template
linesGlobal='\n'.join(['int i;', 'i=1;'])
linesLocal='\n'.join(['int j=i;', 'j++;'])
tmpl = Template(u'''\
void foo() {
if (someRuntimeFlag) {
{{linesGlobal}}
if (anotherRuntimeFlag) {
{{linesLocal}}
}
}
}
''')
print tmpl.render(
linesGlobal=linesGlobal,
linesLocal=linesLocal)
...but saw it produce this:
void foo() {
if (someRuntimeFlag) {
int i;
i=1;
if (anotherRuntimeFlag) {
int j=i;
j++;
}
}
}
...which is not what I want.
I managed to make the output emit proper whitespace prefixes with this:
...
if (someRuntimeFlag) {
{{linesGlobal|indent(8)}}
if (anotherRuntimeFlag) {
{{linesLocal|indent(12)}}
}
}
...but this is arguably bad, since I need to manually count whitespace
for every string I emit...
Surely Jinja2 offers a better way that I am missing?
There's no answer (yet), because quite simply, Jinja2 doesn't support this functionality.
There is, however, an open ticket for this feature - if you care about it, join the discussion there.