Commit 55a50f6c authored by Steven Kabbes's avatar Steven Kabbes Committed by Jacob Potter

add date type to builtin types

This uses NSDate on iOS and java.util.Date on Android
parent f2be27d3
......@@ -2,6 +2,7 @@
// This file generated by Djinni from example.djinni
#import "TXSItemList+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -2,6 +2,7 @@
// This file generated by Djinni from example.djinni
#import "TXSSortItemsCppProxy+Private.h"
#import "DJIDate.h"
#import "DJIError.h"
#import "TXSItemList+Private.h"
#import "TXSSortItems.h"
......
......@@ -8,7 +8,6 @@ import android.widget.EditText;
import java.util.ArrayList;
import java.util.Arrays;
public class MainActivity extends Activity {
private EditText text;
......
......@@ -20,6 +20,7 @@
A29DB13019BCB94300BFC38D /* DJIError.mm in Sources */ = {isa = PBXBuildFile; fileRef = A29DB12C19BCB94300BFC38D /* DJIError.mm */; };
A29DB13119BCB94300BFC38D /* DJIWeakPtrWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = A29DB12E19BCB94300BFC38D /* DJIWeakPtrWrapper.mm */; };
B003051919B70561008E1F67 /* libdjinni_objc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B003051819B70561008E1F67 /* libdjinni_objc.a */; };
B05863941A7980CD00C2CFF5 /* DJIDate.mm in Sources */ = {isa = PBXBuildFile; fileRef = B05863931A7980CD00C2CFF5 /* DJIDate.mm */; };
B097B6BC19B1C07E0047653A /* libtextsort_objc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B097B6BB19B1C07E0047653A /* libtextsort_objc.a */; };
/* End PBXBuildFile section */
......@@ -62,6 +63,8 @@
A29DB12E19BCB94300BFC38D /* DJIWeakPtrWrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DJIWeakPtrWrapper.mm; sourceTree = "<group>"; };
A29DB12F19BCB94300BFC38D /* DJIWeakPtrWrapper+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DJIWeakPtrWrapper+Private.h"; sourceTree = "<group>"; };
B003051819B70561008E1F67 /* libdjinni_objc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libdjinni_objc.a; path = "../../support-lib/build/Debug-iphoneos/libdjinni_objc.a"; sourceTree = "<group>"; };
B05863921A7980CD00C2CFF5 /* DJIDate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DJIDate.h; sourceTree = "<group>"; };
B05863931A7980CD00C2CFF5 /* DJIDate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DJIDate.mm; sourceTree = "<group>"; };
B097B6BB19B1C07E0047653A /* libtextsort_objc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtextsort_objc.a; path = "../../build/Debug-iphoneos/libtextsort_objc.a"; sourceTree = "<group>"; };
/* End PBXFileReference section */
......@@ -167,6 +170,8 @@
65834E3219AC5CDA0061AD3F /* objc-support-lib */ = {
isa = PBXGroup;
children = (
B05863921A7980CD00C2CFF5 /* DJIDate.h */,
B05863931A7980CD00C2CFF5 /* DJIDate.mm */,
A29DB12A19BCB94300BFC38D /* DJICppWrapperCache+Private.h */,
A29DB12B19BCB94300BFC38D /* DJIError.h */,
A29DB12C19BCB94300BFC38D /* DJIError.mm */,
......@@ -271,6 +276,7 @@
files = (
65D7FDFC19AD0CDF0038F82F /* TXSTextboxListenerImpl.m in Sources */,
A29DB13019BCB94300BFC38D /* DJIError.mm in Sources */,
B05863941A7980CD00C2CFF5 /* DJIDate.mm in Sources */,
65D7FDFB19AD0CDF0038F82F /* TXSAppDelegate.m in Sources */,
65D7FDFD19AD0CDF0038F82F /* TXSViewController.mm in Sources */,
A29DB13119BCB94300BFC38D /* DJIWeakPtrWrapper.mm in Sources */,
......
......@@ -50,6 +50,8 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
}
case MString =>
hpp.add("#include <string>")
case MDate =>
hpp.add("#include <chrono>")
case MBinary =>
hpp.add("#include <vector>")
hpp.add("#include <cstdint>")
......
......@@ -364,6 +364,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
case o: MOpaque => o match {
case p: MPrimitive => p.jSig
case MString => "Ljava/lang/String;"
case MDate => "Ljava/util/Date;"
case MBinary => "[B"
case MOptional => e.args.head.base match {
case p: MPrimitive => s"Ljava/lang/${p.jBoxed};"
......
......@@ -47,6 +47,8 @@ class JavaGenerator(spec: Spec) extends Generator(spec) {
java.add("java.util.HashSet")
case MMap =>
java.add("java.util.HashMap")
case MDate =>
java.add("java.util.Date")
case _ =>
}
case _ =>
......@@ -348,6 +350,7 @@ class JavaGenerator(spec: Spec) extends Generator(spec) {
val base = o match {
case p: MPrimitive => if (needRef) p.jBoxed else p.jName
case MString => "String"
case MDate => "Date"
case MBinary => "byte[]"
case MOptional => throw new AssertionError("optional should have been special cased")
case MList => "ArrayList"
......
......@@ -238,6 +238,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
refs.privHeader.add("#import " + q("DJICppWrapperCache+Private.h"))
refs.body.add("#include <utility>")
refs.body.add("#import " + q("DJIError.h"))
refs.body.add("#import " + q("DJIDate.h"))
refs.body.add("#include <exception>")
refs.body.add("!#import " + q(privateHeaderName(cppExtName)))
......@@ -402,6 +403,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
refs.body.add("#import <Foundation/Foundation.h>")
refs.body.add("#include <utility>")
refs.body.add("!#import " + q(privateHeaderName(objcName)))
refs.body.add("#import " + q("DJIDate.h"))
if (r.ext.objc) {
refs.body.add("#import " + q("../" + headerName(ident)))
......@@ -637,6 +639,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
}
case p: MPrimitive => w.wl(s"$to = $from;") // NSNumber is immutable, so are primitive values
case MString => w.wl(s"$to = [$from copy];")
case MDate => w.wl(s"$to = [$from copy];")
case MBinary => w.wl(s"$to = [$from copy];")
case MList => {
val copyName = "copiedValue_" + valueLevel
......@@ -735,6 +738,11 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
w.wl(s"length:$cppIdent.length()")
w.wl("encoding:NSUTF8StringEncoding];")
}
case MDate => {
w.wl(s"$objcType$objcIdent = [NSDate dateWithTimeIntervalSince1970:").nestedN(2) {
w.wl(s"std::chrono::duration_cast<std::chrono::duration<double>>($cppIdent.time_since_epoch()).count()];")
}
}
case MBinary => w.wl(s"$objcType$objcIdent = [NSData dataWithBytes:(&$cppIdent[0]) length:($cppIdent.size())];")
case MOptional => throw new AssertionError("optional should have been special cased")
case MList =>
......@@ -837,6 +845,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
else
w.wl(s"$cppType $cppIdent = $objcIdent;")
case MString => w.wl(s"$cppType $cppIdent([$objcIdent UTF8String], [$objcIdent lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);")
case MDate => w.wl(s"$cppType $cppIdent = ::djinni::convert_date([$objcIdent timeIntervalSince1970]);")
case MBinary =>
w.wl(s"$cppType $cppIdent([$objcIdent length]);")
w.wl(s"[$objcIdent getBytes:(static_cast<void *>($cppIdent.data())) length:[$objcIdent length]];")
......@@ -913,6 +922,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
val base = o match {
case p: MPrimitive => if (needRef) (p.objcBoxed, true) else (p.objcName, false)
case MString => ("NSString", true)
case MDate => ("NSDate", true)
case MBinary => ("NSData", true)
case MOptional => throw new AssertionError("optional should have been special cased")
case MList => ("NSArray", true)
......
......@@ -281,6 +281,7 @@ abstract class Generator(spec: Spec)
def base(m: Meta): String = m match {
case p: MPrimitive => p.cName
case MString => "std::string"
case MDate => "std::chrono::system_clock::time_point"
case MBinary => "std::vector<uint8_t>"
case MOptional => spec.cppOptionalTemplate
case MList => "std::vector"
......@@ -311,6 +312,7 @@ abstract class Generator(spec: Spec)
def toType(expr: MExpr): String = expr.base match {
case MPrimitive(_,_,_,_,_,_,_,_) => valueType
case MDate => valueType
case d: MDef => d.defType match {
case DEnum => valueType
case _ => refType
......
......@@ -39,6 +39,7 @@ case object DRecord extends DefType
case class MPrimitive(_idlName: String, jName: String, jniName: String, cName: String, jBoxed: String, jSig: String, objcName: String, objcBoxed: String) extends MOpaque { val numParams = 0; val idlName = _idlName }
case object MString extends MOpaque { val numParams = 0; val idlName = "string" }
case object MDate extends MOpaque { val numParams = 0; val idlName = "date" }
case object MBinary extends MOpaque { val numParams = 0; val idlName = "binary" }
case object MOptional extends MOpaque { val numParams = 1; val idlName = "optional" }
case object MList extends MOpaque { val numParams = 1; val idlName = "list" }
......@@ -55,6 +56,7 @@ val defaults: Map[String,MOpaque] = immutable.HashMap(
("string", MString),
("binary", MBinary),
("optional", MOptional),
("date", MDate),
("list", MList),
("set", MSet),
("map", MMap))
......
......@@ -212,6 +212,7 @@ private def resolveRecord(scope: Scope, r: Record) {
if (r.derivingTypes.contains(DerivingType.Ord))
throw new Error(f.ident.loc, "Cannot compare collections in Ord deriving (Java limitation)").toException
case MString =>
case MDate =>
case MOptional =>
if (r.derivingTypes.contains(DerivingType.Ord))
throw new Error(f.ident.loc, "Cannot compare optional in Ord deriving").toException
......
//
// Copyright 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "djinni_support.hpp"
#include <chrono>
namespace djinni {
class HDateJniInfo {
public:
const GlobalRef<jclass> clazz { jniFindClass("java/util/Date") };
const jmethodID constructor { jniGetMethodID(clazz.get(), "<init>", "(J)V") };
const jmethodID method_get_time { jniGetMethodID(clazz.get(), "getTime", "()J") };
};
class HDate {
public:
using CppType = std::chrono::system_clock::time_point;
using JniType = jobject;
static std::chrono::system_clock::time_point fromJava(JNIEnv* jniEnv, jobject j) {
static const auto POSIX_EPOCH = std::chrono::system_clock::from_time_t(0);
assert(j != nullptr);
const auto & data = JniClass<HDateJniInfo>::get();
assert(jniEnv->IsInstanceOf(j, data.clazz.get()));
const jlong time_millis = jniEnv->CallLongMethod(j, data.method_get_time);
return POSIX_EPOCH + std::chrono::milliseconds{time_millis};
}
static jobject toJava(JNIEnv* jniEnv, std::chrono::system_clock::time_point value) {
static const auto POSIX_EPOCH = std::chrono::system_clock::from_time_t(0);
const auto & data = JniClass<HDateJniInfo>::get();
const auto cpp_millis = std::chrono::duration_cast<std::chrono::milliseconds>(value - POSIX_EPOCH);
const jlong millis = static_cast<jlong>(cpp_millis.count());
LocalRef<jobject> j(jniEnv, jniEnv->NewObject(data.clazz.get(), data.constructor, millis));
jniExceptionCheck(jniEnv);
return j.release();
}
};
} // namespace djinni
//
// Copyright 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#pragma once
#include <chrono>
namespace djinni {
std::chrono::system_clock::time_point convert_date(const double seconds_since_epoch);
} // namespace djinni
//
// Copyright 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "DJIDate.h"
namespace djinni {
std::chrono::system_clock::time_point convert_date(const double seconds_since_epoch) {
static const auto POSIX_EPOCH = std::chrono::system_clock::from_time_t(0);
const std::chrono::duration<double> converted_date(seconds_since_epoch);
const auto converted_system_date = std::chrono::duration_cast<std::chrono::system_clock::duration>(converted_date);
return POSIX_EPOCH + converted_system_date;
}
} // namespace djinni
......@@ -24,6 +24,7 @@
"sources": [
"objc/DJIWeakPtrWrapper.mm",
"objc/DJIError.mm",
"objc/DJIDate.mm",
],
"include_dirs": [
"objc",
......
......@@ -10,3 +10,4 @@
@import "test.djinni"
@import "inttypes.djinni"
@import "constants.djinni"
@import "date.djinni"
date_record = record {
created_at: date;
}
map_date_record = record {
dates_by_id: map<string, date>;
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#pragma once
#include <chrono>
#include <utility>
struct DateRecord final {
std::chrono::system_clock::time_point created_at;
DateRecord(
std::chrono::system_clock::time_point created_at) :
created_at(std::move(created_at)) {
}
};
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#pragma once
#include <chrono>
#include <string>
#include <unordered_map>
#include <utility>
struct MapDateRecord final {
std::unordered_map<std::string, std::chrono::system_clock::time_point> dates_by_id;
MapDateRecord(
std::unordered_map<std::string, std::chrono::system_clock::time_point> dates_by_id) :
dates_by_id(std::move(dates_by_id)) {
}
};
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
package com.dropbox.djinni.test;
import java.util.Date;
public final class DateRecord {
/*package*/ final Date mCreatedAt;
public DateRecord(
Date createdAt) {
this.mCreatedAt = createdAt;
}
public Date getCreatedAt() {
return mCreatedAt;
}
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
package com.dropbox.djinni.test;
import java.util.Date;
import java.util.HashMap;
public final class MapDateRecord {
/*package*/ final HashMap<String, Date> mDatesById;
public MapDateRecord(
HashMap<String, Date> datesById) {
this.mDatesById = datesById;
}
public HashMap<String, Date> getDatesById() {
return mDatesById;
}
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#include "NativeDateRecord.hpp" // my header
#include "HDate.hpp"
namespace djinni_generated {
jobject NativeDateRecord::toJava(JNIEnv* jniEnv, DateRecord c) {
djinni::LocalRef<jobject> j_created_at(jniEnv, ::djinni::HDate::toJava(jniEnv, c.created_at));
const auto & data = djinni::JniClass<::djinni_generated::NativeDateRecord>::get();
jobject r = jniEnv->NewObject(data.clazz.get(), data.jconstructor, j_created_at.get());
djinni::jniExceptionCheck(jniEnv);
return r;
}
DateRecord NativeDateRecord::fromJava(JNIEnv* jniEnv, jobject j) {
assert(j != nullptr);
const auto & data = djinni::JniClass<::djinni_generated::NativeDateRecord>::get();
return DateRecord(
::djinni::HDate::fromJava(jniEnv, djinni::LocalRef<jobject>(jniEnv, jniEnv->GetObjectField(j, data.field_mCreatedAt)).get()));
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#pragma once
#include "date_record.hpp"
#include "djinni_support.hpp"
namespace djinni_generated {
class NativeDateRecord final {
public:
using CppType = DateRecord;
using JniType = jobject;
static jobject toJava(JNIEnv*, DateRecord);
static DateRecord fromJava(JNIEnv*, jobject);
const djinni::GlobalRef<jclass> clazz { djinni::jniFindClass("com/dropbox/djinni/test/DateRecord") };
const jmethodID jconstructor { djinni::jniGetMethodID(clazz.get(), "<init>", "(Ljava/util/Date;)V") };
const jfieldID field_mCreatedAt { djinni::jniGetFieldID(clazz.get(), "mCreatedAt", "Ljava/util/Date;") };
private:
NativeDateRecord() {}
friend class djinni::JniClass<::djinni_generated::NativeDateRecord>;
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#include "NativeMapDateRecord.hpp" // my header
#include "HDate.hpp"
#include "HMap.hpp"
#include "HString.hpp"
namespace djinni_generated {
jobject NativeMapDateRecord::toJava(JNIEnv* jniEnv, MapDateRecord c) {
djinni::LocalRef<jobject> j_dates_by_id(jniEnv, ::djinni::HMap<::djinni::HString, ::djinni::HDate>::toJava(jniEnv, c.dates_by_id));
const auto & data = djinni::JniClass<::djinni_generated::NativeMapDateRecord>::get();
jobject r = jniEnv->NewObject(data.clazz.get(), data.jconstructor, j_dates_by_id.get());
djinni::jniExceptionCheck(jniEnv);
return r;
}
MapDateRecord NativeMapDateRecord::fromJava(JNIEnv* jniEnv, jobject j) {
assert(j != nullptr);
const auto & data = djinni::JniClass<::djinni_generated::NativeMapDateRecord>::get();
return MapDateRecord(
::djinni::HMap<::djinni::HString, ::djinni::HDate>::fromJava(jniEnv, djinni::LocalRef<jobject>(jniEnv, jniEnv->GetObjectField(j, data.field_mDatesById)).get()));
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#pragma once
#include "djinni_support.hpp"
#include "map_date_record.hpp"
namespace djinni_generated {
class NativeMapDateRecord final {
public:
using CppType = MapDateRecord;
using JniType = jobject;
static jobject toJava(JNIEnv*, MapDateRecord);
static MapDateRecord fromJava(JNIEnv*, jobject);
const djinni::GlobalRef<jclass> clazz { djinni::jniFindClass("com/dropbox/djinni/test/MapDateRecord") };
const jmethodID jconstructor { djinni::jniGetMethodID(clazz.get(), "<init>", "(Ljava/util/HashMap;)V") };
const jfieldID field_mDatesById { djinni::jniGetFieldID(clazz.get(), "mDatesById", "Ljava/util/HashMap;") };
private:
NativeMapDateRecord() {}
friend class djinni::JniClass<::djinni_generated::NativeMapDateRecord>;
};
} // namespace djinni_generated
......@@ -2,6 +2,7 @@
// This file generated by Djinni from inttypes.djinni
#import "DBAssortedIntegers+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -2,6 +2,7 @@
// This file generated by Djinni from client_interface.djinni
#import "DBClientReturnedRecord+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -3,6 +3,7 @@
#import "DBConstants+Private.h"
#import "DBConstants+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -4,6 +4,7 @@
#import "DBCppExceptionCppProxy+Private.h"
#import "DBCppException.h"
#import "DBCppExceptionCppProxy+Private.h"
#import "DJIDate.h"
#import "DJIError.h"
#include <exception>
#include <utility>
......
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#import "DBDateRecord.h"
#include "date_record.hpp"
#import <Foundation/Foundation.h>
@interface DBDateRecord ()
- (id)initWithCppDateRecord:(const DateRecord &)dateRecord;
- (DateRecord)cppDateRecord;
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#import <Foundation/Foundation.h>
@interface DBDateRecord : NSObject
- (id)initWithDateRecord:(DBDateRecord *)dateRecord;
- (id)initWithCreatedAt:(NSDate *)createdAt;
@property (nonatomic, readonly) NSDate *createdAt;
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#import "DBDateRecord+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@implementation DBDateRecord
- (id)initWithDateRecord:(DBDateRecord *)dateRecord
{
if (self = [super init]) {
_createdAt = [dateRecord.createdAt copy];
}
return self;
}
- (id)initWithCreatedAt:(NSDate *)createdAt
{
if (self = [super init]) {
_createdAt = createdAt;
}
return self;
}
- (id)initWithCppDateRecord:(const DateRecord &)dateRecord
{
if (self = [super init]) {
_createdAt = [NSDate dateWithTimeIntervalSince1970:
std::chrono::duration_cast<std::chrono::duration<double>>(dateRecord.created_at.time_since_epoch()).count()];
}
return self;
}
- (DateRecord)cppDateRecord
{
std::chrono::system_clock::time_point createdAt = ::djinni::convert_date([_createdAt timeIntervalSince1970]);
return DateRecord(
std::move(createdAt));
}
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#import "DBMapDateRecord.h"
#include "map_date_record.hpp"
#import <Foundation/Foundation.h>
@interface DBMapDateRecord ()
- (id)initWithCppMapDateRecord:(const MapDateRecord &)mapDateRecord;
- (MapDateRecord)cppMapDateRecord;
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#import <Foundation/Foundation.h>
@interface DBMapDateRecord : NSObject
- (id)initWithMapDateRecord:(DBMapDateRecord *)mapDateRecord;
- (id)initWithDatesById:(NSDictionary *)datesById;
@property (nonatomic, readonly) NSDictionary *datesById;
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from date.djinni
#import "DBMapDateRecord+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@implementation DBMapDateRecord
- (id)initWithMapDateRecord:(DBMapDateRecord *)mapDateRecord
{
if (self = [super init]) {
NSMutableDictionary *_datesByIdTempDictionary = [NSMutableDictionary dictionaryWithCapacity:[mapDateRecord.datesById count]];
for (id key_0 in mapDateRecord.datesById) {
id copiedKey_0, copiedValue_0;
copiedKey_0 = [key_0 copy];
id value_0 = [mapDateRecord.datesById objectForKey:key_0];
copiedValue_0 = [value_0 copy];
[_datesByIdTempDictionary setObject:copiedValue_0 forKey:copiedKey_0];
}
_datesById = _datesByIdTempDictionary;
}
return self;
}
- (id)initWithDatesById:(NSDictionary *)datesById
{
if (self = [super init]) {
_datesById = datesById;
}
return self;
}
- (id)initWithCppMapDateRecord:(const MapDateRecord &)mapDateRecord
{
if (self = [super init]) {
NSMutableDictionary *_datesByIdTempDictionary = [NSMutableDictionary dictionaryWithCapacity:mapDateRecord.dates_by_id.size()];
for (const auto & cppPair_0 : mapDateRecord.dates_by_id) {
NSString *objcKey_0 = [[NSString alloc] initWithBytes:cppPair_0.first.data()
length:cppPair_0.first.length()
encoding:NSUTF8StringEncoding];
NSDate *objcValue_0 = [NSDate dateWithTimeIntervalSince1970:
std::chrono::duration_cast<std::chrono::duration<double>>(cppPair_0.second.time_since_epoch()).count()];
[_datesByIdTempDictionary setObject:objcValue_0 forKey:objcKey_0];
}
_datesById = _datesByIdTempDictionary;
}
return self;
}
- (MapDateRecord)cppMapDateRecord
{
std::unordered_map<std::string, std::chrono::system_clock::time_point> datesById;
for (id objcKey_0 in _datesById) {
std::string cppKey_0([objcKey_0 UTF8String], [objcKey_0 lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
std::chrono::system_clock::time_point cppValue_0 = ::djinni::convert_date([[_datesById objectForKey:objcKey_0] timeIntervalSince1970]);
datesById.emplace(std::move(cppKey_0), std::move(cppValue_0));
}
return MapDateRecord(
std::move(datesById));
}
@end
......@@ -2,6 +2,7 @@
// This file generated by Djinni from map.djinni
#import "DBMapListRecord+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -2,6 +2,7 @@
// This file generated by Djinni from map.djinni
#import "DBMapRecord+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -2,6 +2,7 @@
// This file generated by Djinni from nested_collection.djinni
#import "DBNestedCollection+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -2,6 +2,7 @@
// This file generated by Djinni from primitive_list.djinni
#import "DBPrimitiveList+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -2,6 +2,7 @@
// This file generated by Djinni from derivings.djinni
#import "DBRecordWithDerivings+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -3,6 +3,7 @@
#import "DBRecordWithNestedDerivings+Private.h"
#import "DBRecordWithDerivings+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -2,6 +2,7 @@
// This file generated by Djinni from set.djinni
#import "DBSetRecord+Private.h"
#import "DJIDate.h"
#import <Foundation/Foundation.h>
#include <utility>
......
......@@ -12,6 +12,7 @@
#import "DBSetRecord+Private.h"
#import "DBTestHelpers.h"
#import "DBTokenCppProxy+Private.h"
#import "DJIDate.h"
#import "DJIError.h"
#include <exception>
#include <utility>
......
......@@ -3,6 +3,7 @@
#import "DBTokenCppProxy+Private.h"
#import "DBToken.h"
#import "DJIDate.h"
#import "DJIError.h"
#include <exception>
#include <utility>
......
#import <XCTest/XCTest.h>
#import "DBDateRecord+Private.h"
#include <chrono>
#include <thread>
#include "date_record.hpp"
@interface DBDateRecordTests : XCTestCase
@end
@implementation DBDateRecordTests
- (void)setUp
{
[super setUp];
}
- (void)tearDown
{
[super tearDown];
}
-(BOOL)datesAreAlmostEqual:(NSDate*)date1 date2:(NSDate*)date2 {
const double time_1 = [date1 timeIntervalSince1970];
const double time_2 = [date2 timeIntervalSince1970];
// assert that time's are accurate to 1 microsecond
if (time_1 > time_2) {
return time_1 - time_2 < 1.0e-6;
} else if (time_2 > time_1) {
return time_2 - time_1 < 1.0e-6;
}
return time_1 == time_2;
}
- (void)testObjcRoundTrip
{
NSDate *now = [NSDate date];
DBDateRecord *date1 = [[DBDateRecord alloc] initWithCreatedAt:now];
const auto cpp_date1 = [date1 cppDateRecord];
DBDateRecord *date2 = [[DBDateRecord alloc] initWithCppDateRecord:cpp_date1];
const auto cpp_date2 = [date2 cppDateRecord];
DBDateRecord *date3 = [[DBDateRecord alloc] initWithCppDateRecord:cpp_date2];
const auto cpp_date3 = [date3 cppDateRecord];
const bool cpp_is_equal = cpp_date1.created_at == cpp_date2.created_at && cpp_date2.created_at == cpp_date3.created_at;
// cpp is a integer representation (with less precision than NSDate), so direct comparison will work
XCTAssertTrue(cpp_is_equal);
// We need to make a single pass through djinni to lose the precision of date1.
// So date1 and date2 will only be close, not exactly equal.
XCTAssertTrue([self datesAreAlmostEqual:date1.createdAt date2:date2.createdAt]);
// However date2 and date3 will have already had precision stripped (by a pass through djinni),
// so they can be directly compared.
XCTAssertTrue([date2.createdAt isEqualToDate:date3.createdAt]);
}
- (void)testCppRoundTrip
{
const auto now = std::chrono::system_clock::now();
DateRecord cpp_date_now(now);
DBDateRecord *objcDate = [[DBDateRecord alloc] initWithCppDateRecord:cpp_date_now];
const auto boomerang_cpp_date = [objcDate cppDateRecord];
XCTAssertTrue(now == boomerang_cpp_date.created_at);
}
@end
......@@ -39,12 +39,16 @@
6D66A8AD1A3B0A3200B312E8 /* DBConstants.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D66A8AB1A3B0A3200B312E8 /* DBConstants.mm */; };
6D66A8B01A3B0A7C00B312E8 /* constants.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D66A8AE1A3B0A7C00B312E8 /* constants.cpp */; };
A2059B6219DF7DDE006A2896 /* DBColorTranslator.mm in Sources */ = {isa = PBXBuildFile; fileRef = A2059B6019DF7DDE006A2896 /* DBColorTranslator.mm */; };
A21557A91A16DC5000084E93 /* DBTokenCppProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = A21557A71A16DC5000084E93 /* DBTokenCppProxy.mm */; };
A227B6A91A0D79F10003BBAC /* assorted_integers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A227B6A71A0D79F10003BBAC /* assorted_integers.cpp */; };
A227B6AD1A0D7A290003BBAC /* DBAssortedIntegers.mm in Sources */ = {isa = PBXBuildFile; fileRef = A227B6AB1A0D7A290003BBAC /* DBAssortedIntegers.mm */; };
A21557A91A16DC5000084E93 /* DBTokenCppProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = A21557A71A16DC5000084E93 /* DBTokenCppProxy.mm */; };
A278D45019BA33CB006FD937 /* DBTestHelpersCppProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = A278D44E19BA33CB006FD937 /* DBTestHelpersCppProxy.mm */; };
A278D45319BA3601006FD937 /* test_helpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A278D45219BA3601006FD937 /* test_helpers.cpp */; };
A2CB54B419BA6E6000A9E600 /* DJIError.mm in Sources */ = {isa = PBXBuildFile; fileRef = A2CB54B319BA6E6000A9E600 /* DJIError.mm */; };
B005349C1A797043009D06EC /* DBDateRecord.mm in Sources */ = {isa = PBXBuildFile; fileRef = B00534971A797043009D06EC /* DBDateRecord.mm */; };
B005349D1A797043009D06EC /* DBMapDateRecord.mm in Sources */ = {isa = PBXBuildFile; fileRef = B005349A1A797043009D06EC /* DBMapDateRecord.mm */; };
B005349E1A7972C3009D06EC /* DBDateRecordTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = B00534921A796EFD009D06EC /* DBDateRecordTests.mm */; };
B064CA091A78DAD5005DAA7C /* DJIDate.mm in Sources */ = {isa = PBXBuildFile; fileRef = B064CA081A78DAD5005DAA7C /* DJIDate.mm */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
......@@ -147,15 +151,15 @@
A2059B5F19DF7DDE006A2896 /* DBColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBColor.h; sourceTree = "<group>"; };
A2059B6019DF7DDE006A2896 /* DBColorTranslator.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBColorTranslator.mm; sourceTree = "<group>"; };
A2059B6119DF7DDE006A2896 /* DBColorTranslator+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBColorTranslator+Private.h"; sourceTree = "<group>"; };
A21557A51A16DC5000084E93 /* DBToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBToken.h; sourceTree = "<group>"; };
A21557A61A16DC5000084E93 /* DBTokenCppProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBTokenCppProxy.h; sourceTree = "<group>"; };
A21557A71A16DC5000084E93 /* DBTokenCppProxy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBTokenCppProxy.mm; sourceTree = "<group>"; };
A21557A81A16DC5000084E93 /* DBTokenCppProxy+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBTokenCppProxy+Private.h"; sourceTree = "<group>"; };
A227B6A71A0D79F10003BBAC /* assorted_integers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = assorted_integers.cpp; sourceTree = "<group>"; };
A227B6A81A0D79F10003BBAC /* assorted_integers.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = assorted_integers.hpp; sourceTree = "<group>"; };
A227B6AA1A0D7A290003BBAC /* DBAssortedIntegers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBAssortedIntegers.h; sourceTree = "<group>"; };
A227B6AB1A0D7A290003BBAC /* DBAssortedIntegers.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBAssortedIntegers.mm; sourceTree = "<group>"; };
A227B6AC1A0D7A290003BBAC /* DBAssortedIntegers+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBAssortedIntegers+Private.h"; sourceTree = "<group>"; };
A21557A51A16DC5000084E93 /* DBToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBToken.h; sourceTree = "<group>"; };
A21557A61A16DC5000084E93 /* DBTokenCppProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBTokenCppProxy.h; sourceTree = "<group>"; };
A21557A71A16DC5000084E93 /* DBTokenCppProxy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBTokenCppProxy.mm; sourceTree = "<group>"; };
A21557A81A16DC5000084E93 /* DBTokenCppProxy+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBTokenCppProxy+Private.h"; sourceTree = "<group>"; };
A278D44C19BA33CB006FD937 /* DBTestHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBTestHelpers.h; sourceTree = "<group>"; };
A278D44D19BA33CB006FD937 /* DBTestHelpersCppProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBTestHelpersCppProxy.h; sourceTree = "<group>"; };
A278D44E19BA33CB006FD937 /* DBTestHelpersCppProxy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBTestHelpersCppProxy.mm; sourceTree = "<group>"; };
......@@ -164,6 +168,17 @@
A278D45219BA3601006FD937 /* test_helpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_helpers.cpp; sourceTree = "<group>"; };
A2CAD0871A16CA1800080DF0 /* token.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = token.hpp; sourceTree = "<group>"; };
A2CB54B319BA6E6000A9E600 /* DJIError.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DJIError.mm; sourceTree = "<group>"; };
B00534921A796EFD009D06EC /* DBDateRecordTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBDateRecordTests.mm; sourceTree = "<group>"; };
B00534941A796F6F009D06EC /* date_record.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = date_record.hpp; sourceTree = "<group>"; };
B00534951A796F6F009D06EC /* map_date_record.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = map_date_record.hpp; sourceTree = "<group>"; };
B00534961A797043009D06EC /* DBDateRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBDateRecord.h; sourceTree = "<group>"; };
B00534971A797043009D06EC /* DBDateRecord.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBDateRecord.mm; sourceTree = "<group>"; };
B00534981A797043009D06EC /* DBDateRecord+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBDateRecord+Private.h"; sourceTree = "<group>"; };
B00534991A797043009D06EC /* DBMapDateRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBMapDateRecord.h; sourceTree = "<group>"; };
B005349A1A797043009D06EC /* DBMapDateRecord.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBMapDateRecord.mm; sourceTree = "<group>"; };
B005349B1A797043009D06EC /* DBMapDateRecord+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBMapDateRecord+Private.h"; sourceTree = "<group>"; };
B064CA061A78D9E3005DAA7C /* DJIDate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DJIDate.h; sourceTree = "<group>"; };
B064CA081A78DAD5005DAA7C /* DJIDate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DJIDate.mm; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -192,6 +207,8 @@
6536CD6919A6C82200DD7715 /* objc-support-lib */ = {
isa = PBXGroup;
children = (
B064CA081A78DAD5005DAA7C /* DJIDate.mm */,
B064CA061A78D9E3005DAA7C /* DJIDate.h */,
A2CB54B319BA6E6000A9E600 /* DJIError.mm */,
6536CD6A19A6C82200DD7715 /* DJIError.h */,
6536CD6B19A6C82200DD7715 /* DJIWeakPtrWrapper+Private.h */,
......@@ -227,6 +244,7 @@
6536CD7919A6C99800DD7715 /* Tests */ = {
isa = PBXGroup;
children = (
B00534921A796EFD009D06EC /* DBDateRecordTests.mm */,
6536CD7A19A6C99800DD7715 /* DBClientInterfaceTests.mm */,
6536CD7B19A6C99800DD7715 /* DBCppExceptionTests.mm */,
6536CD7C19A6C99800DD7715 /* DBMapRecordTests.mm */,
......@@ -279,6 +297,8 @@
65BAE6D619A6C7100035F775 /* generated-cpp */ = {
isa = PBXGroup;
children = (
B00534941A796F6F009D06EC /* date_record.hpp */,
B00534951A796F6F009D06EC /* map_date_record.hpp */,
A227B6A71A0D79F10003BBAC /* assorted_integers.cpp */,
A227B6A81A0D79F10003BBAC /* assorted_integers.hpp */,
A2CAD0871A16CA1800080DF0 /* token.hpp */,
......@@ -306,6 +326,12 @@
65BAE6E319A6C7100035F775 /* generated-objc */ = {
isa = PBXGroup;
children = (
B00534961A797043009D06EC /* DBDateRecord.h */,
B00534971A797043009D06EC /* DBDateRecord.mm */,
B00534981A797043009D06EC /* DBDateRecord+Private.h */,
B00534991A797043009D06EC /* DBMapDateRecord.h */,
B005349A1A797043009D06EC /* DBMapDateRecord.mm */,
B005349B1A797043009D06EC /* DBMapDateRecord+Private.h */,
A227B6AA1A0D7A290003BBAC /* DBAssortedIntegers.h */,
A227B6AB1A0D7A290003BBAC /* DBAssortedIntegers.mm */,
A227B6AC1A0D7A290003BBAC /* DBAssortedIntegers+Private.h */,
......@@ -460,10 +486,13 @@
65BAE70719A6C7100035F775 /* DBCppExceptionCppProxy.mm in Sources */,
65BAE70419A6C7100035F775 /* record_with_nested_derivings.cpp in Sources */,
A2CB54B419BA6E6000A9E600 /* DJIError.mm in Sources */,
B064CA091A78DAD5005DAA7C /* DJIDate.mm in Sources */,
B005349C1A797043009D06EC /* DBDateRecord.mm in Sources */,
A278D45019BA33CB006FD937 /* DBTestHelpersCppProxy.mm in Sources */,
A227B6AD1A0D7A290003BBAC /* DBAssortedIntegers.mm in Sources */,
65BAE70519A6C7100035F775 /* DBClientInterfaceObjcProxy.mm in Sources */,
A227B6A91A0D79F10003BBAC /* assorted_integers.cpp in Sources */,
B005349D1A797043009D06EC /* DBMapDateRecord.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -477,6 +506,7 @@
6536CD8D19A6C9A800DD7715 /* DBClientInterfaceTests.mm in Sources */,
6536CD8E19A6C9A800DD7715 /* DBCppExceptionTests.mm in Sources */,
6536CD9319A6C9A800DD7715 /* DBRecordWithDerivingsObjcTests.mm in Sources */,
B005349E1A7972C3009D06EC /* DBDateRecordTests.mm in Sources */,
6536CD9019A6C9A800DD7715 /* DBNestedCollectionTests.mm in Sources */,
6536CD8F19A6C9A800DD7715 /* DBMapRecordTests.mm in Sources */,
6536CD9419A6C9A800DD7715 /* DBSetRecordTests.mm in Sources */,
......
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