rbplusplus 0.1.1 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/Rakefile +31 -15
  2. data/TODO +20 -0
  3. data/lib/rbplusplus/builders/base.rb +148 -8
  4. data/lib/rbplusplus/builders/class.rb +106 -31
  5. data/lib/rbplusplus/builders/enumeration.rb +40 -0
  6. data/lib/rbplusplus/builders/extension.rb +31 -6
  7. data/lib/rbplusplus/builders/module.rb +12 -6
  8. data/lib/rbplusplus/builders/types_manager.rb +93 -0
  9. data/lib/rbplusplus/extension.rb +69 -41
  10. data/lib/rbplusplus/module.rb +3 -1
  11. data/lib/rbplusplus/transformers/class.rb +67 -0
  12. data/lib/rbplusplus/transformers/constructor.rb +4 -0
  13. data/lib/rbplusplus/transformers/function.rb +27 -0
  14. data/lib/rbplusplus/transformers/method.rb +4 -0
  15. data/lib/rbplusplus/transformers/module.rb +71 -0
  16. data/lib/rbplusplus/transformers/node.rb +77 -0
  17. data/lib/rbplusplus/transformers/node_cache.rb +19 -0
  18. data/lib/rbplusplus/transformers/node_reference.rb +30 -0
  19. data/lib/rbplusplus/transformers/rbgccxml.rb +6 -0
  20. data/lib/rbplusplus/writers/extension.rb +33 -25
  21. data/lib/rbplusplus/writers/multiple_files_writer.rb +42 -2
  22. data/lib/rbplusplus/writers/single_file_writer.rb +5 -0
  23. data/lib/rbplusplus.rb +24 -0
  24. data/test/class_methods_test.rb +55 -0
  25. data/test/classes_test.rb +0 -25
  26. data/test/compiling_test.rb +30 -0
  27. data/test/constructors_test.rb +40 -0
  28. data/test/enumerations_test.rb +63 -0
  29. data/test/file_writers_test.rb +56 -4
  30. data/test/generated/extconf.rb +25 -5
  31. data/test/headers/class_methods.h +41 -0
  32. data/test/headers/complex_static_methods.h +25 -0
  33. data/test/headers/constructors.h +47 -0
  34. data/test/headers/enums.h +77 -0
  35. data/test/headers/external_mapping.h +16 -0
  36. data/test/headers/external_mapping_rice.h +20 -0
  37. data/test/headers/include/helper.h +1 -0
  38. data/test/headers/nested_struct.h +20 -0
  39. data/test/headers/overload.h +28 -0
  40. data/test/headers/subclass.h +42 -0
  41. data/test/headers/to_from_ruby.h +78 -0
  42. data/test/headers/to_from_ruby_source.cpp +22 -0
  43. data/test/headers/ugly_helper.h +18 -0
  44. data/test/headers/ugly_interface.h +115 -0
  45. data/test/headers/ugly_interface_ns.h +8 -0
  46. data/test/nested_test.rb +26 -0
  47. data/test/object_persistence_test.rb +44 -0
  48. data/test/overloading_test.rb +36 -0
  49. data/test/struct_test.rb +22 -0
  50. data/test/subclass_test.rb +31 -0
  51. data/test/test_helper.rb +5 -0
  52. data/test/to_from_ruby_test.rb +24 -0
  53. data/test/wrap_as_test.rb +114 -0
  54. metadata +43 -6
@@ -6,38 +6,46 @@ module RbPlusPlus
6
6
  # file with the appropriate options.
7
7
  class ExtensionWriter < Base
8
8
 
9
- # List of -I directives
10
- attr_accessor :includes
9
+ # Options given from the extension
10
+ attr_accessor :options
11
11
 
12
- # List of -L directives
13
- attr_accessor :library_paths
12
+ def write
13
+ extconf = File.join(working_dir, "extconf.rb")
14
14
 
15
- # List of -l directives
16
- attr_accessor :libraries
15
+ inc_str = @options[:include_paths].flatten.uniq.map {|i| "-I#{i}"}.join(" ")
16
+ inc_str += " " + @options[:cxxflags].flatten.join(" ")
17
+ lib_path_str = @options[:library_paths].flatten.uniq.map {|i| "-L#{i}"}.join(" ")
18
+ lib_str = @options[:libraries].flatten.uniq.map {|i| "-l#{i}"}.join(" ")
19
+ lib_str += " " + @options[:ldflags].flatten.join(" ")
17
20
 
18
- # Extra CXXFLAGS
19
- attr_accessor :cxxflags
21
+ File.open(extconf, "w+") do |file|
22
+ file.puts <<-EOF
23
+ require 'rubygems'
24
+ require 'mkmf-rice'
25
+
26
+ # Add the arguments to the linker flags.
27
+ def append_ld_flags(flags)
28
+ flags = [flags] unless flags.is_a?(Array)
29
+ with_ldflags("\#{$LDFLAGS} \#{flags.join(' ')}") { true }
30
+ end
20
31
 
21
- # Extra LDFLAGS
22
- attr_accessor :ldflags
32
+ $CPPFLAGS += \" -I'#{working_dir}' #{inc_str}\"
33
+ $LDFLAGS += \" #{lib_path_str} #{lib_str}\"
23
34
 
24
- def write
25
- extconf = File.join(working_dir, "extconf.rb")
26
-
27
- @includes ||= []
35
+ if RUBY_PLATFORM =~ /darwin/
36
+ # In order to link the shared library into our bundle with GCC 4.x on OSX, we have to work around a bug:
37
+ # GCC redefines symbols - which the -fno-common prohibits. In order to keep the -fno-common, we
38
+ # remove the flat_namespace (we now have two namespaces, which fixes the GCC clash). Also, we now lookup
39
+ # symbols in both the namespaces (dynamic_lookup).
28
40
 
29
- inc_str = @includes.flatten.uniq.map {|i| "-I#{i}"}.join(" ")
30
- inc_str += " " + @cxxflags.flatten.join(" ")
31
- lib_path_str = @library_paths.flatten.uniq.map {|i| "-L#{i}"}.join(" ")
32
- lib_str = @libraries.flatten.uniq.map {|i| "-l#{i}"}.join(" ")
33
- lib_str += " " + @ldflags.flatten.join(" ")
41
+ $LDSHARED_CXX.gsub!('suppress', 'dynamic_lookup')
42
+ $LDSHARED_CXX.gsub!('-flat_namespace', '')
43
+
44
+ append_ld_flags '-all_load'
45
+ end
34
46
 
35
- File.open(extconf, "w+") do |file|
36
- file.puts "require \"rubygems\""
37
- file.puts "require \"mkmf-rice\""
38
- file.puts %Q($CPPFLAGS = $CPPFLAGS + " -I#{working_dir} #{inc_str}")
39
- file.puts %Q($LDFLAGS = $LDFLAGS + " #{lib_path_str} #{lib_str}")
40
- file.puts "create_makefile(\"#{builder.name}\")"
47
+ create_makefile(\"#{builder.name}\")
48
+ EOF
41
49
  end
42
50
  end
43
51
 
@@ -5,9 +5,41 @@ module RbPlusPlus
5
5
  class MultipleFilesWriter < Base
6
6
 
7
7
  def write
8
+ @to_from_include = ""
9
+ write_to_from_ruby
8
10
  _write_node(builder)
9
11
  end
10
12
 
13
+ # Write out files that include the auto-generated to_/from_ruby constructs.
14
+ def write_to_from_ruby
15
+ # Ignore this if there's nothing to write out
16
+ return if Builders::TypesManager.body.length == 0
17
+
18
+ hpp_file = File.join(working_dir, "_to_from_ruby.rb.hpp")
19
+ cpp_file = File.join(working_dir, "_to_from_ruby.rb.cpp")
20
+
21
+ @to_from_include = "#include \"#{hpp_file}\""
22
+
23
+ include_guard = "__RICE_GENERATED_TO_FROM_RUBY_HPP__"
24
+
25
+ File.open(hpp_file, "w+") do |f|
26
+ f.puts "#ifndef #{include_guard}"
27
+ f.puts "#define #{include_guard}"
28
+ f.puts ""
29
+ f.puts Builders::TypesManager.includes.uniq.join("\n")
30
+ f.puts ""
31
+ f.puts Builders::TypesManager.prototypes.join("\n")
32
+ f.puts ""
33
+ f.puts "#endif // #{include_guard}"
34
+ end
35
+
36
+ File.open(cpp_file, "w+") do |f|
37
+ f.puts @to_from_include
38
+ f.puts ""
39
+ f.puts Builders::TypesManager.body.join("\n");
40
+ end
41
+ end
42
+
11
43
  # How this works:
12
44
  #
13
45
  # We'll recurse through the builder heirarchy, starting at the bottom.
@@ -19,10 +51,15 @@ module RbPlusPlus
19
51
  end
20
52
 
21
53
  filename = if node.parent
22
- node.qualified_name.gsub(/::/, "_")
54
+ "_"+node.qualified_name.gsub(/::/, "_")
23
55
  else
24
56
  node.name
25
57
  end
58
+
59
+ #templated classes
60
+ filename.gsub!(/[ ,<>]/,"_")
61
+ #templates to pointers
62
+ filename.gsub!("*","Ptr")
26
63
 
27
64
  cpp_file = File.join(working_dir, "#{filename}.rb.cpp")
28
65
 
@@ -48,7 +85,8 @@ module RbPlusPlus
48
85
  # * Add a call to the register method
49
86
  node.parent.includes << hpp_include
50
87
 
51
- node.parent.body << "#{register_func}(#{register_func_arg});"
88
+ # Register for proper flattening of the inheritance tree
89
+ node.parent.register_node(node, "#{register_func}(#{register_func_arg});")
52
90
 
53
91
  # Modifications to this current node's code:
54
92
  #
@@ -60,6 +98,8 @@ module RbPlusPlus
60
98
  hpp.puts "#ifndef #{include_guard}"
61
99
  hpp.puts "#define #{include_guard}"
62
100
  hpp.puts ""
101
+ hpp.puts @to_from_include
102
+ hpp.puts ""
63
103
  hpp.puts "void #{register_func}(#{register_func_prototype});"
64
104
  hpp.puts "#endif"
65
105
  end
@@ -7,6 +7,11 @@ module RbPlusPlus
7
7
  def write
8
8
  process_code(builder)
9
9
 
10
+ if Builders::TypesManager.body.length > 0
11
+ # Handle to_from_ruby constructions
12
+ builder.declarations << Builders::TypesManager.body
13
+ end
14
+
10
15
  filename = builder.name
11
16
  cpp_file = File.join(working_dir, "#{filename}.rb.cpp")
12
17
 
data/lib/rbplusplus.rb CHANGED
@@ -6,8 +6,11 @@ require 'rbgccxml'
6
6
 
7
7
  require 'inflector'
8
8
  require 'fileutils'
9
+ require 'singleton'
9
10
  require 'rbplusplus/rbplusplus'
10
11
 
12
+ require 'fileutils'
13
+
11
14
  module RbPlusPlus
12
15
 
13
16
  RBPP_COMMENT = "// This file generated by rb++"
@@ -20,6 +23,8 @@ module RbPlusPlus
20
23
  autoload :ClassBuilder, "rbplusplus/builders/class"
21
24
  autoload :ExtensionBuilder, "rbplusplus/builders/extension"
22
25
  autoload :ModuleBuilder, "rbplusplus/builders/module"
26
+ autoload :EnumerationBuilder, "rbplusplus/builders/enumeration"
27
+ autoload :TypesManager, "rbplusplus/builders/types_manager"
23
28
  end
24
29
 
25
30
  module Writers
@@ -30,3 +35,22 @@ module RbPlusPlus
30
35
  end
31
36
  end
32
37
 
38
+ class String #:nodoc:
39
+ # Functionize attempts to rename a string in a cpp function friendly way.
40
+ #
41
+ # vector<float>::x => vector_float__x
42
+ def functionize
43
+ gsub("::","_").gsub(/[ ,<>]/, "_").gsub("*", "Ptr")
44
+ end
45
+ end
46
+
47
+ require 'rbplusplus/transformers/rbgccxml'
48
+ require 'rbplusplus/transformers/node_cache'
49
+ require 'rbplusplus/transformers/node'
50
+ require 'rbplusplus/transformers/node_reference'
51
+ require 'rbplusplus/transformers/function'
52
+ require 'rbplusplus/transformers/method'
53
+ require 'rbplusplus/transformers/constructor'
54
+ require 'rbplusplus/transformers/class'
55
+ require 'rbplusplus/transformers/module'
56
+
@@ -0,0 +1,55 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Correct handling of static methods" do
4
+ def setup
5
+ if !defined?(@@complex_static)
6
+ super
7
+ @@complex_static = true
8
+ Extension.new "complex" do |e|
9
+ e.sources full_dir("headers/complex_static_methods.h")
10
+ node = e.namespace "complex"
11
+ end
12
+
13
+ require 'complex'
14
+ end
15
+ end
16
+
17
+ specify "should handle complex static methods" do
18
+ Multiply.multiply(SmallInteger.new(2),SmallInteger.new(2)).should == 4
19
+ end
20
+
21
+ end
22
+
23
+ context "Correct handling of encapsulated methods" do
24
+ def setup
25
+ if !defined?(@@encapsulated)
26
+ super
27
+ @@encapsulated = true
28
+ Extension.new "encapsulation" do |e|
29
+ e.sources full_dir("headers/class_methods.h")
30
+ node = e.namespace "encapsulation"
31
+ end
32
+
33
+ require 'encapsulation'
34
+ end
35
+ end
36
+
37
+ specify "should handle private/protected/public" do
38
+ ext = Extended.new
39
+ ext.public_method.should == 1
40
+ should.raise NoMethodError do
41
+ ext.private_method
42
+ end
43
+ should.raise NoMethodError do
44
+ ext.protected_method
45
+ end
46
+ end
47
+
48
+ specify "should handle virtual methods" do
49
+ ext_factory = ExtendedFactory.new
50
+ ext = ext_factory.new_instance
51
+ ext.fundamental_type_virtual_method.should == 1
52
+ ext.user_defined_type_virtual_method.class.should == Base
53
+ end
54
+ end
55
+
data/test/classes_test.rb CHANGED
@@ -40,28 +40,3 @@ context "Extension with wrapped classes" do
40
40
 
41
41
  end
42
42
 
43
- context "Wrapping Classes within classes" do
44
-
45
- def setup
46
- if !defined?(@@nested_built)
47
- super
48
- @@nested_built = true
49
- Extension.new "nested" do |e|
50
- e.sources full_dir("headers/nested_classes.h")
51
- e.namespace "classes"
52
- end
53
-
54
- require 'nested'
55
- end
56
- end
57
-
58
- specify "should properly make nested classes available" do
59
- assert defined?(TestClass)
60
- assert defined?(TestClass::InnerClass)
61
- assert defined?(TestClass::InnerClass::Inner2)
62
-
63
- TestClass.new.should.not.be.nil
64
- TestClass::InnerClass.new.should.not.be.nil
65
- TestClass::InnerClass::Inner2.new.should.not.be.nil
66
- end
67
- end
@@ -126,4 +126,34 @@ context "Compiler settings" do
126
126
  e.write
127
127
  end
128
128
  end
129
+
130
+ specify "should be able to add additional headers as needed" do
131
+ should.not.raise do
132
+ e = Extension.new "external"
133
+ e.working_dir = full_dir("generated")
134
+ e.sources full_dir("headers/external_mapping.h"),
135
+ :includes => full_dir("headers/*rice.h")
136
+ e.build
137
+ e.write
138
+
139
+ file = full_dir("generated/external.rb.cpp")
140
+ contents = File.read(file)
141
+ contents.should.match(%r(headers/external_mapping_rice.h))
142
+ end
143
+ end
144
+
145
+ specify "can specify other source files to be compiled into the extension" do
146
+ Extension.new "source_files" do |e|
147
+ e.sources full_dir("headers/to_from_ruby.h"),
148
+ :include_paths => full_dir("headers"),
149
+ :include_source_files => full_dir("headers/to_from_ruby_source.cpp")
150
+ e.namespace "to_from_ruby"
151
+ end
152
+
153
+ require 'source_files'
154
+
155
+ # Don't know if there's any way to catch this nicely. A failure here
156
+ # is a symbol lookup failure and death to the Ruby VM
157
+ needs_to_ruby(3).value.should == 3
158
+ end
129
159
  end
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Extension with constructors out the whazoo" do
4
+
5
+ # Test is currently broken due to something Rice is or isn't doing.
6
+ xspecify "should make constructors available" do
7
+ Extension.new "constructors" do |e|
8
+ e.sources full_dir("headers/constructors.h")
9
+ node = e.namespace "constructors"
10
+ e.writer_mode :single
11
+ end
12
+
13
+ require 'constructors'
14
+
15
+ should.not.raise NameError do
16
+ # Constructor overloading not yet supported
17
+ # s = StringHolder.new
18
+ # s.set_name "two"
19
+ # s.get_name.should == "two"
20
+
21
+ s2 = StringHolder.new "one"
22
+ s2.get_name.should == "one"
23
+ end
24
+
25
+ should.not.raise NameError do
26
+ # Test complex constructors
27
+ d = DoubleStringHolder.new(StringHolder.new("one"), StringHolder.new("two"))
28
+ one = d.get_one
29
+ puts "Got one #{one.inspect}"
30
+ puts "Name is #{one.get_name}"
31
+ # d.get_one.get_name.should == "one"
32
+ # d.get_two.get_name.should == "two"
33
+ end
34
+
35
+ should.raise TypeError do
36
+ PrivateConstructor.new
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,63 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Wrapping enumerations" do
4
+
5
+ def setup
6
+ if !defined?(@@enums_built)
7
+ super
8
+ @@enums_built = true
9
+ Extension.new "enums" do |e|
10
+ e.sources full_dir("headers/enums.h")
11
+ e.namespace "enums"
12
+ e.writer_mode :single
13
+
14
+ e.module "Mod" do |m|
15
+ m.namespace "inner"
16
+ end
17
+ end
18
+
19
+ require 'enums'
20
+ end
21
+ end
22
+
23
+ specify "should wrap up enums properly" do
24
+ assert defined?(TestEnum)
25
+
26
+ TestEnum::VALUE1.to_i.should == 0
27
+ TestEnum::VALUE2.to_i.should == 1
28
+ TestEnum::VALUE3.to_i.should == 2
29
+ end
30
+
31
+ specify "should wrap up enumerations at proper nesting" do
32
+ assert defined?(Tester::MyEnum)
33
+
34
+ Tester::MyEnum::I_LIKE_MONEY.to_i.should == 3
35
+ Tester::MyEnum::YOU_LIKE_MONEY_TOO.to_i.should == 4
36
+ Tester::MyEnum::I_LIKE_YOU.to_i.should == 7
37
+ end
38
+
39
+ specify "should work in user-defined modules" do
40
+ assert defined?(Mod::InnerEnum)
41
+
42
+ Mod::InnerEnum::INNER_1.to_i.should == 0
43
+ Mod::InnerEnum::INNER_2.to_i.should == 1
44
+ end
45
+
46
+ specify "should allow use of enumerations as types" do
47
+ what_test_enum(TestEnum::VALUE1).should == "We gots enum 0";
48
+
49
+ # Types should be adhered to
50
+ should.raise RuntimeError do
51
+ what_test_enum(Mod::InnerEnum::INNER_1)
52
+ end
53
+
54
+ t = Tester.new
55
+ t.get_enum_description(Tester::MyEnum::YOU_LIKE_MONEY_TOO).should == "You like money!"
56
+ end
57
+
58
+ specify "should properly build to_ruby converters for const enum return types" do
59
+ t = Tester.new
60
+ t.get_an_enum("I like money").should == Tester::MyEnum::I_LIKE_MONEY
61
+ t.get_an_enum("You like money").should == Tester::MyEnum::YOU_LIKE_MONEY_TOO
62
+ end
63
+ end
@@ -23,10 +23,10 @@ context "Multiple file writer (default)" do
23
23
 
24
24
  %w(
25
25
  extconf.rb
26
- Mod.rb.cpp
27
- Mod.rb.hpp
28
- classes_Adder.rb.cpp
29
- classes_Adder.rb.hpp
26
+ _Mod.rb.cpp
27
+ _Mod.rb.hpp
28
+ _classes_Adder.rb.cpp
29
+ _classes_Adder.rb.hpp
30
30
  adder.rb.cpp
31
31
  ).each do |wants|
32
32
  assert_not_nil files.find {|got| File.basename(got) == wants }, "Didn't find #{wants}"
@@ -35,6 +35,37 @@ context "Multiple file writer (default)" do
35
35
 
36
36
  end
37
37
 
38
+ context "Multiple file writer with to_from_ruby" do
39
+
40
+ setup do
41
+ @working_dir = File.expand_path(File.dirname(__FILE__) + "/generated")
42
+
43
+ e = Extension.new "to_from_ruby"
44
+ e.working_dir = @working_dir
45
+ e.sources full_dir("headers/to_from_ruby.h"),
46
+ :include_paths => full_dir("headers"),
47
+ :include_source_files => full_dir("headers/to_from_ruby_source.cpp")
48
+
49
+ e.namespace "to_from_ruby"
50
+
51
+ e.build
52
+ e.write
53
+ end
54
+
55
+ specify "should have proper written out files" do
56
+ files = Dir["#{@working_dir}/*"]
57
+
58
+ %w(
59
+ extconf.rb
60
+ _to_from_ruby.rb.hpp
61
+ _to_from_ruby.rb.cpp
62
+ ).each do |wants|
63
+ assert_not_nil files.find {|got| File.basename(got) == wants }, "Didn't find #{wants}"
64
+ end
65
+ end
66
+
67
+ end
68
+
38
69
  context "Single file writer" do
39
70
 
40
71
  setup do
@@ -66,3 +97,24 @@ context "Single file writer" do
66
97
  end
67
98
 
68
99
  end
100
+
101
+ context "Single file writer with to_from_ruby" do
102
+
103
+ setup do
104
+ Extension.new "to_from_ruby" do |e|
105
+ e.sources full_dir("headers/to_from_ruby.h"),
106
+ :include_paths => full_dir("headers"),
107
+ :include_source_files => full_dir("headers/to_from_ruby_source.cpp")
108
+ e.namespace "to_from_ruby"
109
+
110
+ e.writer_mode :single
111
+ end
112
+
113
+ end
114
+
115
+ specify "should have compiled properly" do
116
+ should.not.raise LoadError do
117
+ require 'to_from_ruby'
118
+ end
119
+ end
120
+ end
@@ -1,5 +1,25 @@
1
- require "rubygems"
2
- require "mkmf-rice"
3
- $CPPFLAGS = $CPPFLAGS + " -I/home/roelofs/projects/rbplusplus/test/generated "
4
- $LDFLAGS = $LDFLAGS + " "
5
- create_makefile("adder")
1
+ require 'rubygems'
2
+ require 'mkmf-rice'
3
+
4
+ # Add the arguments to the linker flags.
5
+ def append_ld_flags(flags)
6
+ flags = [flags] unless flags.is_a?(Array)
7
+ with_ldflags("#{$LDFLAGS} #{flags.join(' ')}") { true }
8
+ end
9
+
10
+ $CPPFLAGS += " -I'/home/roelofs/projects/rbplusplus/test/generated' -I/home/roelofs/projects/rbplusplus/test/headers "
11
+ $LDFLAGS += " "
12
+
13
+ if RUBY_PLATFORM =~ /darwin/
14
+ # In order to link the shared library into our bundle with GCC 4.x on OSX, we have to work around a bug:
15
+ # GCC redefines symbols - which the -fno-common prohibits. In order to keep the -fno-common, we
16
+ # remove the flat_namespace (we now have two namespaces, which fixes the GCC clash). Also, we now lookup
17
+ # symbols in both the namespaces (dynamic_lookup).
18
+
19
+ $LDSHARED_CXX.gsub!('suppress', 'dynamic_lookup')
20
+ $LDSHARED_CXX.gsub!('-flat_namespace', '')
21
+
22
+ append_ld_flags '-all_load'
23
+ end
24
+
25
+ create_makefile("to_from_ruby")
@@ -0,0 +1,41 @@
1
+ namespace encapsulation {
2
+ class Base {
3
+ protected:
4
+ virtual int protectedMethod() {
5
+ return -1;
6
+ }
7
+ public:
8
+ virtual int fundamentalTypeVirtualMethod() = 0;
9
+ virtual ~Base() {}
10
+ virtual Base *userDefinedTypeVirtualMethod() = 0;
11
+ };
12
+
13
+ class Extended : public Base {
14
+ private:
15
+ void privateMethod() {
16
+ }
17
+ protected:
18
+ int protectedMethod() {
19
+ return 1;
20
+ }
21
+ public:
22
+ Extended() {}
23
+ int publicMethod() {
24
+ return this->protectedMethod();
25
+ }
26
+ int fundamentalTypeVirtualMethod() {
27
+ return 1;
28
+ }
29
+ Base *userDefinedTypeVirtualMethod() {
30
+ return new Extended();
31
+ }
32
+ };
33
+
34
+ class ExtendedFactory {
35
+ public:
36
+ ExtendedFactory() {}
37
+ Base *newInstance() {
38
+ return new Extended();
39
+ }
40
+ };
41
+ }
@@ -0,0 +1,25 @@
1
+ #ifndef __COMPLEX_H__
2
+ #define __COMPLEX_H__
3
+
4
+ namespace complex {
5
+ class SmallInteger {
6
+ private:
7
+ int i;
8
+ public:
9
+ SmallInteger(int i) {
10
+ this->i = i;
11
+ }
12
+ int getI() {
13
+ return this->i;
14
+ }
15
+ };
16
+
17
+ class Multiply {
18
+ public:
19
+ static int multiply(SmallInteger *i, SmallInteger *i2) {
20
+ return i->getI() * i2->getI();
21
+ }
22
+ };
23
+ }
24
+
25
+ #endif
@@ -0,0 +1,47 @@
1
+ #ifndef __CONSTRUCTORS_H__
2
+ #define __CONSTRUCTORS_H__
3
+
4
+ #include <string>
5
+
6
+ using namespace std;
7
+
8
+ namespace constructors {
9
+ class StringHolder {
10
+ private:
11
+ std::string name;
12
+ public:
13
+ StringHolder() { }
14
+ StringHolder(std::string name) {
15
+ setName(name);
16
+ }
17
+ inline std::string getName() {
18
+ return name;
19
+ }
20
+ inline void setName(std::string name) {
21
+ this->name = name;
22
+ }
23
+ };
24
+
25
+ class DoubleStringHolder {
26
+ private:
27
+ StringHolder *one, *two;
28
+ public:
29
+ DoubleStringHolder(StringHolder *one, StringHolder *two) {
30
+ this->one = one;
31
+ this->two = two;
32
+ }
33
+ inline StringHolder *getOne() {
34
+ return this->one;
35
+ }
36
+ inline StringHolder *getTwo() {
37
+ return this->two;
38
+ }
39
+ };
40
+
41
+ class PrivateConstructor {
42
+ private:
43
+ PrivateConstructor() {}
44
+ };
45
+ }
46
+
47
+ #endif