rbplusplus 0.1.1 → 0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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